正则expression式在grep中包含A,B,C …但不是Z的文件

花了几个小时试图用这个问题的部分答案自己来回答这个问题; 所以我很抱歉,如果这已经得到回答,但结合我能find的部分解决scheme来正确执行这个search似乎超出了我。

我在做什么:在文件的任何位置以任意顺序search包含多个唯一string的文件,但不包含文件中任何位置的其他特定string。

这是我迄今为止的search:

pcregrep -riM '^(?=.*uniquestringA)(?=.*uniquestringB)(?=.*uniquestringC)(?=.*uniquestringD)(?=.*uniquestringE).*$' . | xargs grep -Li 'uniquestringZ' 

我意识到,这是可怕的,可怕的错误,因为我似乎甚至不能让多行search工作,而忽略了string出现的顺序。

任何帮助是极大的赞赏。

虽然它需要大量的grep调用,但是你可以用findgrep以简单和符合POSIX的方式写出来:

 find . -type f \ -exec grep -q "stringA" {} \; \ -exec grep -q "stringB" {} \; \ -exec grep -q "stringC" {} \; \ -exec grep -q "stringD" {} \; \ ! -exec grep -q "stringZ" {} \; \ -print # or whatever to do with matches 

如果你的grep有向前看,你应该可以做到

 ^(?!.*Z)(?=.*A)(?=.*B)(?=.*C)(.*)$ 

看到它的工作

有了这个文件:

 $ cat /tmp/grep_tgt.txt A,B,C # should match A,B,C,D # should match A,C,D # no match, lacking upper b A,B,C,Z # no match, has upper z 

你可以使用Perl的一个班轮:

 $ perl -ne 'print if /^(?!.*Z)(?=.*A)(?=.*B)(?=.*C)(.*)$/' /tmp/grep_tgt.txt A,B,C # should match A,B,C,D # should match 

用文件名称:

 $ find . -type f ./.DS_Store ./ABC ./ABCZ ./ACD ./sub/ABCD 

你可以用perl来过滤文件名:

 $ find . -type f | perl -ne 'print if /^(?!.*Z)(?=.*A)(?=.*B)(?=.*C)(.*)$/' ./ABC ./sub/ABCD 

如果你想读取文件内容来测试一个模式(比如grep),你可以这样做:

 $ find . -type f | xargs perl -ne 'print "$ARGV: $&\n" if /^ (?!.*Z)(?=.*A)(?=.*B)(?=.*C)(.*)$/' ./1.txt: ABC # should match ./2.txt: A,B,C,D # should match 

在那里我把四个文件放在一个目录(1.txt .. 4.txt)与1.txt和2.txt中的文本匹配。