Reputation: 1366
I want to search with grep for a pattern in a number of files which I specified in a previous step and which are now stored in a text file.
Lets say, in the first step, I used
grep -l 'pattern1' *.csv >> ~/filenames.txt
to list the filenames of all the csv files which contained pattern1 and save these filenames into filenames.txt
Now I would like to search all of the above files for a second pattern, pattern2. I'm looking for a command like
grep -?? 'pattern2' ~/filenames.txt
where -?? tells grep to look for filenames in filenames.txt I know that
grep -f patternfile.txt *.csv
Would search all csv files for the patterns defined in patternfile.txt. Is there an analog command for searching all files specified in a file full of filenames?
I'm also happy to hear about alternative solution to my overall problem, e.g. somehow combining step 1 and 2 without the interim filenames.txt but it would also be interesting to know about the analog grep command, if it exists.
To be clear, I am not just looking for files which contain pattern1 and pattern2. I'm interested in all occurrences for pattern2 (and then actually count them) in files in which pattern1 appears at least once.
Upvotes: 1
Views: 2159
Reputation: 440162
To:
try the following (assumes that you're either on Linux or BSD/OSX):
grep -l --null 'pattern1' *.csv | xargs -0 grep 'pattern2'
-l
tells grep
to print only the input filename in case of a match--null
separates the filenames with NULsxargs -0
parses the NUL-separated filenames into individual arguments and passes them to the 2nd grep
command.On Linux (with GNU utilities), you can simplify the command somewhat, assuming you're not worried about filenames with embedded newlines (very rare):
grep -l 'pattern1' *.csv | xargs -d '\n' grep 'pattern2'
-d '\n'
makes xargs
consider each input line as a whole an individual argument.Upvotes: 2
Reputation: 786031
You can use xargs
for this:
xargs -I {} grep -H 'pattern' {} < ~/filenames.txt
grep
will run against filename on each line from ~/filenames
file.
This will also work with spaces in filenames.
Upvotes: 3