How do I pass a list of files to grep

  • I am using find and getting a list of files I want to grep through. How do I pipe that list to grep?

  • Well, the generic case that works with any command that writes to stdout is to use xargs, which will let you attach any number of command-line arguments to the end of a command:

    $ find … | xargs grep 'search'
    

    Or to embed the command in your grep line with backticks or $(), which will run the command and substitute its output:

    $ grep 'search' $(find …)
    

    Note that these commands don't work if the file names contain whitespace, or certain other “weird characters” (\'" for xargs, \[*? for $(find …)).


    However, in the specific case of find the ability to execute a program on the given arguments is built-in:

    $ find … -exec grep 'search' {} \;
    

    Everything between -exec and ; is the command to execute; {} is replaced with the filename found by find. That will execute a separate grep for each file; since grep can take many filenames and search them all, you can change the ; to + to tell find to pass all the matching filenames to grep at once:

    $ find … -exec grep 'search' {} \+
    

    Should be noted that first two forms do not works with filenames containing spaces.

    I prefer `find ... -type f -print0 | xargs -r0 grep 'search' /dev/null`. QED. While `-exec +` is very efficient, it does not exist on all version of find.

    Sadly I can not check you correct 3 times.

    I suggest using the `-exec`, rather than than the `xargs`. If you use the `-exec` in `find`, it will create only one shell to grep for the content. If you use the `xargs`, it will create two shells: one for the `find` and the other for the `xargs`.

    by experiment I find that the `$ find … -exec grep 'search' {} \+` form is *much* the fastest.

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM