How to grep for two patterns in multiple files
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?
04 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 RegistrationrequestI 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/File1Then 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 hereHope 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
aandrfor 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.
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) More in general
"Zoraya ter Beek, age 29, just died by assisted suicide in the Netherlands. She was physically healthy, but psychologically depressed. It's an abomination that an entire society would actively facilitate, even encourage, someone ending their own life because they had no hope. Th…"