hea*_*xas 204 regex linux string grep
我试图用来grep匹配包含两个不同字符串的行.我尝试了以下但是这匹配包含string1 或 string2的行,这不是我想要的.
grep 'string1\|string2' filename
Run Code Online (Sandbox Code Playgroud)
那么我如何grep只匹配包含两个字符串的行?
小智 196
我认为这就是你要找的东西:
grep -E "string1|string2" filename
Run Code Online (Sandbox Code Playgroud)
我认为答案是这样的:
grep 'string1.*string2\|string2.*string1' filename
Run Code Online (Sandbox Code Playgroud)
只匹配两者都存在的情况,而不是一个或两个或两者.
dhe*_*aur 177
您可以使用 grep 'string1' filename | grep 'string2'
要么, grep 'string1.*string2\|string2.*string1' filename
Kin*_*xit 26
要在任何地方搜索包含所有单词的文件:
grep -ril \'action\' | xargs grep -il \'model\' | xargs grep -il \'view_type\'
Run Code Online (Sandbox Code Playgroud)
第一个grep启动递归搜索(r),忽略case(i)并列出(打印出)l一个术语('action'带有单引号)匹配的文件的名称(在单个引号中)出现在文件的任何位置.
随后的greps搜索其他术语,保留不区分大小写并列出匹配的文件.
您将获得的最终文件列表将是包含这些术语的文件,可以按文件中的任何顺序排列.
tch*_*ist 15
如果你有一个有限正则表达式grep的-P选项perl,你可以使用
grep -P '(?=.*string1)(?=.*string2)'
Run Code Online (Sandbox Code Playgroud)
它具有处理重叠字符串的优点.使用perlas 稍微简单一点grep,因为您可以更直接地指定和逻辑:
perl -ne 'print if /string1/ && /string2/'
Run Code Online (Sandbox Code Playgroud)
Leo*_*Leo 12
你的方法几乎是好的,只缺少-w
grep -w 'string1\|string2' filename
Run Code Online (Sandbox Code Playgroud)
不要尝试使用 grep 来执行此操作,而是使用 awk。要在 grep 中匹配 2 个正则表达式 R1 和 R2,您可能会认为:
grep 'R1.*R2|R2.*R1'
Run Code Online (Sandbox Code Playgroud)
而在 awk 中则为:
awk '/R1/ && /R2/'
Run Code Online (Sandbox Code Playgroud)
但如果R2与 重叠或者是 的子集怎么办R1?grep 命令根本不起作用,而 awk 命令却可以。假设您想要查找包含the和 的行heat:
$ echo 'theatre' | grep 'the.*heat|heat.*the'
$ echo 'theatre' | awk '/the/ && /heat/'
theatre
Run Code Online (Sandbox Code Playgroud)
你必须使用 2 个 grep 和一个管道:
$ echo 'theatre' | grep 'the' | grep 'heat'
theatre
Run Code Online (Sandbox Code Playgroud)
当然,如果您实际上要求它们分开,您始终可以在 awk 中编写与 grep 中使用的相同的正则表达式,并且还有替代的 awk 解决方案,这些解决方案不涉及在每个可能的序列中重复正则表达式。
抛开这一点,如果您想扩展您的解决方案以匹配 3 个正则表达式 R1、R2 和 R3,该怎么办?在 grep 中,这将是以下糟糕的选择之一:
grep 'R1.*R2.*R3|R1.*R3.*R2|R2.*R1.*R3|R2.*R3.*R1|R3.*R1.*R2|R3.*R2.*R1' file
grep R1 file | grep R2 | grep R3
Run Code Online (Sandbox Code Playgroud)
而在 awk 中则简洁、明显、简单、高效:
awk '/R1/ && /R2/ && /R3/'
Run Code Online (Sandbox Code Playgroud)
现在,如果您实际上想要匹配文字字符串 S1 和 S2 而不是正则表达式 R1 和 R2,该怎么办?您根本无法在一次调用 grep 中做到这一点,您必须在调用 grep 之前编写代码来转义所有 RE 元字符:
S1=$(sed 's/[^^]/[&]/g; s/\^/\\^/g' <<< 'R1')
S2=$(sed 's/[^^]/[&]/g; s/\^/\\^/g' <<< 'R2')
grep 'S1.*S2|S2.*S1'
Run Code Online (Sandbox Code Playgroud)
或者再次使用 2 个 grep 和一个管道:
grep -F 'S1' file | grep -F 'S2'
Run Code Online (Sandbox Code Playgroud)
这又是糟糕的选择,而使用 awk 你只需使用字符串运算符而不是正则表达式运算符:
awk 'index($0,S1) && index($0.S2)'
Run Code Online (Sandbox Code Playgroud)
现在,如果您想在一个段落而不是一行中匹配 2 个正则表达式该怎么办?无法在 grep 中完成,在 awk 中微不足道:
awk -v RS='' '/R1/ && /R2/'
Run Code Online (Sandbox Code Playgroud)
跨越整个文件怎么样?再次无法在 grep 中完成,在 awk 中微不足道(这次我使用 GNU awk 进行多字符 RS 以便简洁,但在任何 awk 中都没有更多代码,或者您可以选择一个您知道不会的控制字符在 RS 的输入中执行相同操作):
awk -v RS='^$' '/R1/ && /R2/'
Run Code Online (Sandbox Code Playgroud)
因此,如果您想在一行、段落或文件中查找多个正则表达式或字符串,那么不要使用 grep,而应使用 awk。
|正则表达式中的运算符表示或.也就是说string1或string2匹配.你可以这样做:
grep 'string1' filename | grep 'string2'
Run Code Online (Sandbox Code Playgroud)
这会将第一个命令的结果传递给第二个grep.这应该只给你两条线匹配.
正如人们建议的 perl 和 python 以及复杂的 shell 脚本,这里有一个简单的awk方法:
awk '/string1/ && /string2/' filename
Run Code Online (Sandbox Code Playgroud)
查看了对已接受答案的评论:不,这不支持多行;但这也不是问题作者所要求的。