1

我正在尝试找到一种方法来确定可能在文件的不同部分中具有 str1 和 str2 的文件的名称。grep str1 | grep str2 将不起作用,因为 grep str2 将在包含 str1 的行上运行。我可以得到一个包含 str1 的文件列表和一个包含 str2 的文件列表,然后寻找交集,但这效率低下。一种更有效的方法是让 grep str1 输出文件列表,然后让 grep str2 对其进行操作,但这意味着 grep 将一遍又一遍地打开、读取和关闭同一个文件。也许最理想的方法是打开一个文件,grep for str1 和 str2,然后确定该文件是否同时包含 str1 和 str2,但我无法创建这样的命令。我想它应该看起来类似于这个 find 。-name "*" -exec grep "str1" && grep "

4

5 回答 5

2

使用 GNU awk (gawk):

awk -v RS='\0' -v str1="$str1" -v str2="$str2" '
   index($0,str1) && index($0,str2) { print FILENAME; nextfile }
' file1 file2 filen

使用任何 awk:

awk -v str1="$str1" -v str2="$str2" '
   FNR == 1             { found[1] = found[2] = 0 }
   index($0,str1)       { found[1]++ }
   index($0,str2)       { found[2]++ }
   found[1] && found[2] { files[FILENAME] }
   END { for (file in files) print file }
' file1 file2 filen
于 2013-01-05T17:01:18.207 回答
0

我认为 awk 更适合这项任务。这是您可以做到的一种方法:

awk -v str1="$str1" -v str2="$str2" '
  FNR == 1 { m1 = m2 = 0 }
  index($0, str1) { m1 = 1 }
  index($0, str2) { m2 = 1 }
  m1 && m2 { print FILENAME; nextfile }' file1 file2 filen

这假定$str1$str2设置为您要搜索的字符串。该解决方案一次性完成匹配,并在找到两个字符串后立即退出。

稍微优化的版本:

awk -v str1="$str1" -v str2="$str2" '
  FNR == 1 { m1 = m2 = 0 }
  !m1 && index($0, str1) { m1 = 1 }
  !m2 && index($0, str2) { m2 = 1 }
  m1 && m2 { print FILENAME; nextfile }' file1 file2 filen

更新:

添加了Ed Morton在下面的评论中提到的错误修复和优化。另请注意,旧版本的 awk 中的语句可能存在一些可移植性问题,请参阅GNU awk 附录 Bnextfile中有关该主题的讨论。该声明已被接受以包含在 POSIX 标准中,因此将来应该会更广泛地使用。nextfile

于 2013-01-05T15:35:31.057 回答
0
于 2013-01-05T14:20:48.423 回答
-1

尝试使用 regexp 之类的(str1.*str2|str2.*str1)。我不确定,可能你需要使用egrep而不是grep

于 2013-01-05T14:23:35.447 回答
-2

If str1 occurs before str2 then you can use

find . -name "str1*str2"
于 2013-01-05T14:21:45.230 回答