101

I'm trying to produce this behaviour:

grep 192.168.1 *.txt

By passing a string into grep via Xargs but it is going on the end instead of as the first parameter.

echo 192.168.1 | xargs grep  *.txt

I need to tell xargs (or something similar) to put the incoming string between 'grep' and '*' instead of on the end.

How do I do this?

andy boot
  • 1,163
  • 2
  • 9
  • 8
  • Similar to [How can I find files and then use xargs to move them?](http://unix.stackexchange.com/questions/90886/how-can-i-find-files-and-then-use-xargs-to-move-them). – manatwork Sep 20 '13 at 12:18

2 Answers2

159
$ echo 192.168.1. | xargs -I{} grep {} *.txt

Example

Sample files:

$ cat {1..3}.txt
192.168.1
192.168.1
192.168.1

Example run:

# example uses {} but you can use whatever, such as -I{} or -Ifoo
$ echo 192.168.1. | xargs -I{} grep {} *.txt
1.txt:192.168.1.
2.txt:192.168.1.
3.txt:192.168.1.
Rob Bos
  • 4,250
  • 1
  • 11
  • 12
slm
  • 363,520
  • 117
  • 767
  • 871
  • Thanks, it works. But why? What are you replacing with -I ? I don't get it. – e18r Dec 21 '16 at 16:18
  • 13
    It seems the curly brackets are a place holder. You can replace {} with anything you like: echo 192.168.1. | xargs -I pholder grep pholder *.txt – denormalizer Jun 19 '17 at 00:47
  • 1
    @denormalizer I am not sure why, but using `{}` as place holder is not working for me, instead, `%` works for me. – zyy Mar 02 '20 at 17:08
  • 1
    @zyy Would be interesting to know what OS you are running. I think I've got it working on Ubuntu and CentOS – denormalizer Mar 02 '20 at 22:23
  • @denormalizer I think mine is CentOS Linux release 7.7.1908. – zyy Mar 03 '20 at 03:21
5

Another approach:

find . -name \*.txt -print0 | xargs -0 grep 192.168.1

This will not overflow the shell's command line length with too many file names. To avoid confusing xargs/grep with file names that have spaces, -print0 and -0 options will delineate each found name with a null rather than a LF.

HalosGhost
  • 4,732
  • 10
  • 33
  • 41
Bill Hoag
  • 159
  • 1
  • 3