我想找到有“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。希望这能有所帮助。

其他回答

文件模式*.sh对于防止目录被检查很重要。当然,一些测试也可以防止这种情况发生。

for f in *.sh
do
  a=$( grep -n -m1 abc $f )
  test -n "${a}" && z=$( grep -n efg $f | tail -n 1) || continue 
  (( ((${z/:*/}-${a/:*/})) > 0 )) && echo $f
done

The

grep -n -m1 abc $f 

搜索最大1个匹配项并返回(-n)行数。 如果找到一个匹配(test -n…),找到efg的最后一个匹配(找到所有,并使用tail -n 1取最后一个匹配)。

z=$( grep -n efg $f | tail -n 1)

其他的继续。

由于结果类似于18:foofile.sh String alf="abc";我们需要从“:”开始切到行尾。

((${z/:*/}-${a/:*/}))

如果第二个表达式的最后一个匹配超过了第一个表达式的第一个匹配,则应返回正结果。

然后我们报告文件名echo $f。

这个也能用吗?!

perl -lpne 'print $ARGV if /abc.*?efg/s' file_list

$ARGV包含从file_list读取当前文件时的文件名 /s修饰符跨换行搜索。

如果您对模式序列不感兴趣,可以使用grep。

grep -l "pattern1" filepattern*.* | xargs grep "pattern2"

例子

grep -l "vector" *.cpp | xargs grep "map"

Grep -l将找到与第一个模式匹配的所有文件,xargs将为第二个模式查找Grep。希望这能有所帮助。

如果你对你要找的两个字符串'abc'和'efg'之间的距离有一些估计,你可以使用:

grep -r . -e 'abc' -A num1 -B num2 | grep 'efg'

这样,第一个grep将返回'abc' + #num1行,后面是#num2行,第二个grep将筛选所有这些以获得'efg'。 然后您将知道它们同时出现在哪些文件中。

这可以通过首先使用tr用其他字符替换换行符来轻松完成:

tr '\n' '\a' | grep -o 'abc.*def' | tr '\a' '\n'

这里,我使用警报字符\a (ASCII 7)来代替换行符。 这在你的文本中几乎找不到,而且grep可以用一个.匹配它,或者专门用\a匹配它。