grep中的正则表达式包含A,B,C ......但不包含Z的文件

时间:2014-07-29 17:41:47

标签: regex linux grep

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

我尝试做什么:在目录中搜索包含多个唯一字符串的文件,文件中的任何位置,但不包含文件中任何位置的其他特定字符串。

这是我到目前为止的搜索:

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

我意识到这是可怕的,可怕的错误,因为我甚至无法让多行搜索工作,同时忽略字符串出现的顺序。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

如果你的grep有预测,你应该能够做到

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

See it work

使用此文件:

$ 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 one liner:

$ 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
./A-B-C
./A-B-C-Z
./A-C-D
./sub/A-B-C-D

您可以使用perl:

过滤文件名
$ find . -type f | perl -ne 'print if /^(?!.*Z)(?=.*A)(?=.*B)(?=.*C)(.*)$/'
./A-B-C
./sub/A-B-C-D

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

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

我将四个文件放在一个目录(1.txt .. 4.txt)中,文本在1.txt和2.txt中匹配。

答案 1 :(得分:1)

虽然它需要大量的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