I have multiple files in multiple directories, and I need a grep command which can return the output only when both the patterns are present in the file. The patterns are like AccessToken and Registrationrequest. The patterns are not in the same line. AccessToken can be in one line and Registrationrequest can be in another line. Also search the same recursively across all files in all directories.

Tried

grep -r "string1” /directory/file | grep "string 2” grep -rl 'string 1' | xargs grep 'string2' -l /directory/ file grep -e string1 -e string2 

Nothing works

Can anyone please help?

0

4 Answers

The following command can print out when the file matches the search criteria:

grep -Zril 'String1' | xargs -0 grep -il 'String2' 

Here is an example:

~/tmp$ ls Dir1 Dir2 File1 File2 cat File1 AccessToken is not here Registrationrequest it is here cat File2 iAccess ByteMe Registrationrequest 

I copied both File1 and File2 into the Dir1 and Dir2 for testing:

~/tmp$ grep -Zril 'AccessToken' | xargs -0 grep -il 'Registrationrequest' File1 Dir2/File1 Dir1/File1 

Then if you want to see what is in the files add the following to the end of the search:

xargs grep -E "AccessToken|Registrationrequest" 

Example:

~/tmp$ grep -Zril 'AccessToken' | xargs -0 grep -il 'Registrationrequest' | xargs grep -E "AccessToken|Registrationrequest" File1:AccessToken is not here File1:Registrationrequest it is here Dir2/File1:AccessToken is not here Dir2/File1:Registrationrequest it is here Dir1/File1:AccessToken is not here Dir1/File1:Registrationrequest it is here 

Hope this helps!

Just in case the files are very large and making two passes on them is expensive and you want just the filenames, using find+awk:

find . -type f -exec awk 'FNR == 1 {a=0; r=0} /AccessToken/{a=1} /Registrationrequest/{r=1} a && r {print FILENAME; nextfile}' {} + 
  • we set two flag variables a and r for when the corresponding patterns were found, cleared at the start of each file (FNR == 1)
  • when both variables are true, we print the filename and move on to the next file.
2
grep -Erzl 'STR1.*STR2|STR2.*STR1' 

where option -z ends up slurping the files as a single line.

More precisely:

grep -Erzl 'AccessToken.*Registrationrequest|Registrationrequest.*AccessToken' 

while loop

This may not be as clever or resource-effective as other solutions, but it works:

while read -rd '' filename; do if grep -q "AccessToken" "$filename" && grep -q "Registrationrequest" "$filename" then echo "$filename" fi done < <(find . -type f -print0) 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy