花了几个小时试图用这个问题的部分答案自己来回答这个问题; 所以我很抱歉,如果这已经得到回答,但结合我能find的部分解决scheme来正确执行这个search似乎超出了我。
我在做什么:在文件的任何位置以任意顺序search包含多个唯一string的文件,但不包含文件中任何位置的其他特定string。
这是我迄今为止的search:
pcregrep -riM '^(?=.*uniquestringA)(?=.*uniquestringB)(?=.*uniquestringC)(?=.*uniquestringD)(?=.*uniquestringE).*$' . | xargs grep -Li 'uniquestringZ'
我意识到,这是可怕的,可怕的错误,因为我似乎甚至不能让多行search工作,而忽略了string出现的顺序。
任何帮助是极大的赞赏。
虽然它需要大量的grep调用,但是你可以用find
和grep
以简单和符合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中的文本匹配。