Issue
I am creating a bash pipeline where I want to find files that contain specific text and then do something with only those files. I can successfully get the list of files using the find
/xargs
pairing:
$ find . -type f -print0 | xargs -0 grep -l mysearchtext
./dir1/my file.txt
./thefile.pdf
Now that I have the files that match, I want to perform another operation on those files only, something like this:
$ find . -type f -print0 | xargs -0 grep -l mysearchtext | xargs open
This will fail, as the second xargs
call interprets ./dir1/my file.txt
as two files.
Any suggestions on how to accomplish this last part of the pipeline?
Solution
As long as your version of grep
supports the --null
option (which makes it use the null character as a delimiter after filenames, very like find ... -print0
), you can use that:
find . -type f -print0 | xargs -0 grep -l --null mysearchtext | xargs -0 open
As jhnc points out in a comment, it's also possible to use grep -q
as a test with find
's -exec
primary (and you can also replace the -print0 | xargs -0
with -exec ... +
):
find . -type f -exec grep -q mysearchtext {} \; -print0 | xargs -0 open
Since that's all within the find
test expression, you can also replace the -print0 | xargs -0
with -exec ... +
:
find . -type f -exec grep -q mysearchtext {} \; -exec open {} +
Note the difference between -exec ... \;
, which runs the command separately for each file and can be used as a test, and -exec ... +
which runs the command on batches of files (like xargs
), and therefore cannot be used to test individual files.
Answered By - Gordon Davisson Answer Checked By - Timothy Miller (WPSolving Admin)