我有多个目录中的多个文件,我需要一个 grep 命令,它仅当文件中同时存在两种模式时才返回输出。模式类似于AccessToken
和Registrationrequest
。模式不在同一行。AccessToken
可以在一行中,也Registrationrequest
可以在另一行中。还可以在所有目录中的所有文件中递归搜索相同的内容。
尝试过
grep -r "string1” /directory/file | grep "string 2”
grep -rl 'string 1' | xargs grep 'string2' -l /directory/ file
grep -e string1 -e string2
毫无效果
有人可以帮忙吗?
答案1
当文件符合搜索条件时,以下命令可以打印出来:
grep -Zril 'String1' | xargs -0 grep -il 'String2'
以下是一个例子:
~/tmp$ ls
Dir1 Dir2 File1 File2
cat File1
AccessToken is not here
Registrationrequest it is here
cat File2
iAccess
ByteMe Registrationrequest
我将和都复制File1
到和File2
中进行测试:Dir1
Dir2
~/tmp$ grep -Zril 'AccessToken' | xargs -0 grep -il 'Registrationrequest'
File1
Dir2/File1
Dir1/File1
然后,如果您想查看文件中的内容,请将以下内容添加到搜索的末尾:
xargs grep -E "AccessToken|Registrationrequest"
例子:
~/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
希望这可以帮助!
答案2
如果文件非常大,对它们进行两次传递的开销很大,而您只想要文件名,则使用find
+ awk
:
find . -type f -exec awk 'FNR == 1 {a=0; r=0} /AccessToken/{a=1} /Registrationrequest/{r=1} a && r {print FILENAME; nextfile}' {} +
- 我们设置了两个标志变量
a
,r
当找到相应的模式时,在每个文件开始时清除(FNR == 1
) - 当两个变量都为真时,我们会打印文件名并转到下一个文件。
答案3
grep -Erzl 'STR1.*STR2|STR2.*STR1'
其中选项-z
最终将文件合并为一行。
更确切地说:
grep -Erzl 'AccessToken.*Registrationrequest|Registrationrequest.*AccessToken'
答案4
while
环形
这可能不像其他解决方案那样聪明或节省资源,但它确实有效:
while read -rd '' filename; do
if grep -q "AccessToken" "$filename" &&
grep -q "Registrationrequest" "$filename"
then
echo "$filename"
fi
done < <(find . -type f -print0)