我需要查找特定字符串出现两次或更多次的文件。
例如,对于三个文件:
文件1:
Hello World!
文件2:
Hello World!
Hello !
文件3:
Hello World!
Hello
Hello Again.
-
我想grep Hello
并且只获取文件2
& 3
。
答案 0 :(得分:19)
这个怎么样:
grep -o -c Hello * | awk -F: '{if ($2 > 1){print $1}}'
答案 1 :(得分:4)
由于问题标记为grep
,因此以下是仅使用该实用程序和bash
(不需要awk
)的解决方案:
#!/bin/bash
for file in *
do
if [ "$(grep -c "Hello" "${file}")" -gt 1 ]
then
echo "${file}"
fi
done
可以是单行:
for file in *; do if [ "$(grep -c "Hello" "${file}")" -gt 1 ]; then echo "${file}"; fi; done
for file in *
语句。grep -c
返回与模式匹配的行数,一行上的多个匹配项仍然只计算一条匹配的行。if [ ... -gt 1 ]
测试文件中是否匹配多行。如果是这样的话:echo ${file}
打印文件名。答案 2 :(得分:1)
此awk
将打印2
或更多Hello
awk 'FNR==1 {if (a>1) print f;a=0} /Hello/ {a++} {f=FILENAME} END {if (a>1) print f}' *
file2
file3
答案 3 :(得分:1)
在阅读完您的问题之后,我想您也希望在一行中找到案例hello hello
。 (find files where a specific string appears twice or more.
)所以我想出了这个单行:
awk -v p="hello" 'FNR==1{x=0}{x+=gsub(p,p);if(x>1){print FILENAME;nextfile}}' *
p
是您要搜索的模式一点点测试:
kent$ head f*
==> f <==
hello hello world
==> f2 <==
hello
==> f3 <==
hello
hello
SK-Arch 22:27:00 /tmp/test
kent$ awk -v p="hello" 'FNR==1{x=0}{x+=gsub(p,p);if(x>1){print FILENAME;nextfile}}' f*
f
f3
答案 4 :(得分:1)
你需要的是一个grep
,它可以识别行结尾的模式(“你好”后跟任何东西(可能是行结尾),然后是“你好”)
当grep
逐行处理您的文件时,它(本身)不是作业的正确工具 - ,除非您设法将整个文件塞入一行。
现在,这很容易,例如使用tr
命令,用空格替换行结尾:
if cat $file | tr '\n' ' ' | grep -q 'hello.*hello'
then
echo "$file matches"
fi
即使在包含许多(比如100000)行的大型文件上也非常有效,并且通过grep
调用--max-count=1
可以提高效率,使其在匹配后停止搜索被发现了。两个hellos是否在同一条线上并不重要。
答案 5 :(得分:0)
grep -c Hello * | egrep -v':[01] $'| sed's /:[0-9] * $ //'
答案 6 :(得分:0)
另一种方式:
grep Hello * | cut -d: -f1 | uniq -d
Grep表示包含'Hello'的行;只保留文件名;只打印重复项。
答案 7 :(得分:0)
管道输入脚本语言可能会过大,但通常比仅使用awk
grep -rnc "Hello" . | ruby -ne 'file, count = $_.split(":"); puts "#{file}: #{count}" if count&.to_i >= 2'
因此,您的输入,我们得到
$ grep -rnc "Hello" . | ruby -ne 'file, count = $_.split(":"); puts "#{file}: #{count}" if count&.to_i >= 2'
./2: 2
./3: 3
或者忽略计数
grep -rnc "Hello" . | ruby -ne 'file, _ = $_.split(":"); puts file if count&.to_i >= 2'