我正在尝试找到一种方法来确定可能在文件的不同部分中具有 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 "
问问题
156 次
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 回答