grep – 排除不是字符串子串的字符串

我通过以下示例在Ubuntu 16.04上解释我的问题:该文件是:

# cat file aaa aaaxxx aaaxxx*aaa aaa=aaaxxx bbbaaaccc aaaddd/aaaxxx 

我想显示包含aaa但不在aaaxxx 唯一组合中的所有行。 我想要这样的输出:

 # grep SOMETHING-HERE file … aaa aaaxxx*aaa (second aaa is the hit) aaa=aaaxxx (first aaa is the hit) bbbaaaccc (aaa in any other combination but not aaaxxx) aaaddd/aaaxxx (similar to above) 

我试过像grep -v aaaxxx file | grep aaa这样的东西 grep -v aaaxxx file | grep aaa结果如下:

 aaa bbbaaaccc 

要么

 # egrep -P '(?<!aaaxxx )aaa' file grep: die angegebenen Suchmuster stehen in Konflikt zueinander (the pattern are in contradiction) 

有没有(简单)可能性? 当然它不需要是grep 。 谢谢

使用perl风格的超前运算符是直截了当的 – 使用-P开关在grep的Perl兼容正则表达式(PCRE)模式下可用:

 $ grep -P 'aaa(?!xxx)' file aaa aaaxxx* aaa aaa =aaaxxx bbb aaa ccc aaa ddd/aaaxxx 

(输出中的粗体格式表示grep突出显示的匹配部分)


虽然零长度前瞻很方便,但您可以使用GNU扩展正则表达式(ERE)语法实现相同的输出,例如匹配aaa后跟最多2个x字符后跟非x字符或行尾即

 grep -E 'aaax{0,2}([^x]|$)' file 

甚至使用GNU基本正则表达式(BRE)语法

 grep 'aaax\{0,2\}\([^x]\|$\)' file 

匹配为

 aaa aaaxxx* aaa aaa= aaaxxx bbb aaac cc aaad dd/aaaxxx