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

mus*_*ach 4 command-line bash grep

我用以下示例解释了我在 Ubuntu 16.04 上的问题:文件是:

# cat file
aaa
aaaxxx
aaaxxx*aaa
aaa=aaaxxx
bbbaaaccc
aaaddd/aaaxxx
Run Code Online (Sandbox Code Playgroud)

我想显示其包含的所有行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)
Run Code Online (Sandbox Code Playgroud)

我尝试了以下grep -v aaaxxx file | grep aaa结果:

aaa
bbbaaaccc
Run Code Online (Sandbox Code Playgroud)

或者

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

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

ste*_*ver 6

使用 perl 样式的前瞻运算符很简单 - 在 grep 的 Perl 兼容正则表达式 (PCRE) 模式中使用-P开关可用:

$ grep -P 'aaa(?!xxx)' file
aaa
aaaxxx*aaa
aaa=aaaxxx
bbbaaaccc
aaaddd/aaaxxx
Run Code Online (Sandbox Code Playgroud)

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


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

grep -E 'aaax{0,2}([^x]|$)' file
Run Code Online (Sandbox Code Playgroud)

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

grep 'aaax\{0,2\}\([^x]\|$\)' file
Run Code Online (Sandbox Code Playgroud)

哪个匹配为

aaa
aaaxxx*aaa
aaa=aaaxxx
bbbaaaccc
aaaddd/aaaxxx
Run Code Online (Sandbox Code Playgroud)