包含两个或多个特定字符串的Grep文件

时间:2014-05-30 18:20:48

标签: unix grep

我需要查找特定字符串出现两次或更多次的文件。

例如,对于三个文件:

文件1:

Hello World!

文件2:

Hello World!
Hello !

文件3:

Hello World!
Hello
Hello Again.

-

我想grep Hello并且只获取文件2& 3

8 个答案:

答案 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

解释

  • 您可以使用要获取所有数据文件的shell扩展来修改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'