Ubuntu – What does “xargs grep” do

command linegrepxargs

I know the grep command and I am learning about the functionalities of xargs, so I read through this page which gives some examples on how to use the xargs command.

I am confused by the last example, example 10. It says "The xargs command executes the grep command to find all the files (among the files provided by find command) that contained a string ‘stdlib.h’"

$ find . -name '*.c' | xargs grep 'stdlib.h'
./tgsthreads.c:#include
./valgrind.c:#include
./direntry.c:#include
./xvirus.c:#include
./temp.c:#include
...
...
...

However, what is the difference to simply using

$ find . -name '*.c' | grep 'stdlib.h'

?

Obviously, I am still struggling with what exactly xargs is doing, so any help is appreciated!

Best Answer

$ find . -name '*.c' | grep 'stdlib.h'

This pipes the output (stdout)* from find to (stdin of)* grep 'stdlib.h' as text (ie the filenames are treated as text). grep does its usual thing and finds the matching lines in this text (any file names which themselves contain the pattern). The contents of the files are never read.

$ find . -name '*.c' | xargs grep 'stdlib.h'

This constructs a command grep 'stdlib.h' to which each result from find is an argument - so this will look for matches inside each file found by find (xargs can be thought of as turning its stdin into arguments to the given commands)*

Use -type f in your find command, or you will get errors from grep for matching directories. Also, if the filenames have spaces, xargs will screw up badly, so use the null separator by adding -print0 and xargs -0 for more reliable results:

find . -type f -name '*.c' -print0 | xargs -0 grep 'stdlib.h'

*added these extra explanatory points as suggested in comment by @cat