我想过滤与文本文件中包含下一行的所有模式完全匹配的所有行:
c1 and c2 and c15 => r1
c1 and c3 and c11 => r2
c1 and c2 => r3
c2 and c16 => r4
我尝试过grep
使用:
grep -w "c1" file | grep -w "c2"
它返回正确答案:
c1 and c2 and c15 => r1
c1 and c2 => r3
但是当我嵌套超过 6 个grep
命令时,它会返回错误:
Command ' grep' not found
但类似的还有18个
grep
我知道可以嵌套的命令数量存在限制。是否存在另一种方法来执行此操作?
非常感谢。
答案1
Command ' grep' not found
这听起来很像一个拼写错误,您在管道字符后面打了一个不间断的空格,而不是常规的空格。请注意空格是命令名称的一部分,对于常规空格,这需要显式引用或转义空格,例如使用
... | " grep"`
但对于某些键盘映射(例如我的),管道是 AltGr-something,不间断空格是 AltGr-space,如果您释放中间的修饰键有点太慢,就会发生错误。 (或者在 Mac 上使用 Option 而不是 AltGr,同样的事情)
尝试重新输入命令行。长期的解决方法可能是修改键盘映射以删除该陷阱,或者开始键入... |grep
,至少这样您更有可能获得更明显的差异。
答案2
使用awk
:
awk -v arrayvar="c1,c2" '
{
split(arrayvar, a, ",")
for(i in a){
r="(^|" FS ")" a[i] "($|" FS ")"
if($0 !~ r) next
}
print
}' input
我们正在使用split()
功能。
split(s, a [, r [, seps] ])
将字符串 s 拆分为数组 a 和正则表达式 r 上的分隔符数组 seps,并返回字段数。
然后我们检查该行是否包含所有模式。
r="(^|" FS ")" a[i] "($|" FS ")"
^
以or (字段分隔符)开头的正则表达式FS
,具有您的模式,然后以ora[i]
结尾$
FS
如果该行不包含该模式,我们将跳过它。
答案3
如果您grep
有 PCRE 支持,请尝试以下操作:
grep -P '(?=.*c1 )(?=.*c2)' file
注意后面的空格c1
,这样就不会匹配了c15
。