我想找到有“abc”和“efg”的文件,这两个字符串在该文件中的不同行。一个包含以下内容的文件:

blah blah..
blah blah..
blah abc blah
blah blah..
blah blah..
blah blah..
blah efg blah blah
blah blah..
blah blah..

应该匹配。


当前回答

#!/bin/bash
shopt -s nullglob
for file in *
do
 r=$(awk '/abc/{f=1}/efg/{g=1;exit}END{print g&&f ?1:0}' file)
 if [ "$r" -eq 1 ];then
   echo "Found pattern in $file"
 else
   echo "not found"
 fi
done

其他回答

这应该可以工作:

cat FILE | egrep 'abc|efg'

如果有多个匹配项,可以使用grep -v过滤掉

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

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

例子

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

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

在所有文件中递归搜索(在每个文件中的多行中),同时存在两个字符串(即string1和string2在不同的行中,并且都存在于同一个文件中):

grep -r -l 'string1' * > tmp; while read p; do grep -l 'string2' $p; done < tmp; rm tmp 

在所有文件中递归搜索(在每个文件中的多行中),使用EITHER字符串存在(即string1和string2在不同的行中,并且在同一个文件中存在):

grep -r -l 'string1\|string2' * 

文件模式*.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。

遗憾的是,你不能。来自grep文档:

grep搜索指定的输入FILEs(或标准输入,如果没有指定文件,或如果给出了一个连字符减号(-)作为文件名),以查找包含与给定PATTERN匹配的行。