103

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,193

2 Answers2

162
$ 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,380
slm
  • 369,824
  • Thanks, it works. But why? What are you replacing with -I ? I don't get it. – e18r Dec 21 '16 at 16:18
  • 14
    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,790
Bill Hoag
  • 159