我想找到有“abc”和“efg”的文件,这两个字符串在该文件中的不同行。一个包含以下内容的文件:
blah blah..
blah blah..
blah abc blah
blah blah..
blah blah..
blah blah..
blah efg blah blah
blah blah..
blah blah..
应该匹配。
我想找到有“abc”和“efg”的文件,这两个字符串在该文件中的不同行。一个包含以下内容的文件:
blah blah..
blah blah..
blah abc blah
blah blah..
blah blah..
blah blah..
blah efg blah blah
blah blah..
blah blah..
应该匹配。
当前回答
如果您对模式序列不感兴趣,可以使用grep。
grep -l "pattern1" filepattern*.* | xargs grep "pattern2"
例子
grep -l "vector" *.cpp | xargs grep "map"
Grep -l将找到与第一个模式匹配的所有文件,xargs将为第二个模式查找Grep。希望这能有所帮助。
其他回答
虽然sed选项是最简单、最简单的,但遗憾的是,LJ的一行程序并不是最可移植的。那些受困于C Shell(而不是bash)版本的人将需要摆脱他们的刘海:
sed -e '/abc/,/efg/\!d' [file]
不幸的是,这一行在bash等中不起作用。
用银搜索器:
ag 'abc.*(\n|.)*efg' your_filename
与戒指持有者的答案相似,但用ag代替。银色搜索者的速度优势可能在这里大放异彩。
我非常依赖于pcregrep,但是对于更新的grep,您不需要安装它的许多特性。只需使用grep -P。
在OP的问题的例子中,我认为以下选项很好地发挥了作用,第二好的选项符合我对问题的理解:
grep -Pzo "abc(.|\n)*efg" /tmp/tes*
grep -Pzl "abc(.|\n)*efg" /tmp/tes*
我将文本复制为/tmp/test1,删除'g'并保存为/tmp/test2。下面的输出显示,第一个显示匹配的字符串,第二个只显示文件名(典型的-o显示匹配,典型的-l只显示文件名)。请注意,'z'对于多行是必要的,'(.|\n)'意味着匹配'换行符以外的任何内容'或'换行符' -即任何内容:
user@host:~$ grep -Pzo "abc(.|\n)*efg" /tmp/tes*
/tmp/test1:abc blah
blah blah..
blah blah..
blah blah..
blah efg
user@host:~$ grep -Pzl "abc(.|\n)*efg" /tmp/tes*
/tmp/test1
要确定你的版本是否足够新,运行man grep,看看顶部是否出现类似的内容:
-P, --perl-regexp
Interpret PATTERN as a Perl regular expression (PCRE, see
below). This is highly experimental and grep -P may warn of
unimplemented features.
它来自GNU grep 2.10。
这应该可以工作:
cat FILE | egrep 'abc|efg'
如果有多个匹配项,可以使用grep -v过滤掉
如果你对你要找的两个字符串'abc'和'efg'之间的距离有一些估计,你可以使用:
grep -r . -e 'abc' -A num1 -B num2 | grep 'efg'
这样,第一个grep将返回'abc' + #num1行,后面是#num2行,第二个grep将筛选所有这些以获得'efg'。 然后您将知道它们同时出现在哪些文件中。