使用grep计算大量文件中字符串的所有出现次数


289

我有一堆日志文件。我需要找出一个字符串在所有文件中出现了多少次。

grep -c string *

退货

...
file1:1
file2:0
file3:0
...

使用管道,我只能获取出现一次或多次出现的文件:

grep -c string * | grep -v :0

...
file4:5
file5:1
file6:2
...

我怎样才能只获得合并计数?(如果返回file4:5, file5:1, file6:2,我想取回8。)


1
你能告诉我grep -v:0做什么吗?。我知道它计数出现次数大于0的文件。-v选项和:0是什么意思?请让我知道。
Gautham Honnavara'5

@GauthamHonnavara grep:0查找与字符串:0匹配的行。-v是一种反转搜索的选项,因此,代替使用grep -v:0意味着找到不包含:0的所有行,因此具有file4:5和file27:193的行将全部通过,因为它们不包含: 0
penguin359

您可以使用空格选择多个文件。grep file1 file2 --options
Dnyaneshwar Harer

Answers:


288
cat * | grep -c string

9
这具有相同的局限性,即它仅在一行上计算多次出现。我猜测这种情况在这种情况下是可以的。
Michael Haren

@Michael Haren是的,一行中可能只有一个字符串出现。
泽利科菲

2
我宁愿这样做,grep -c string<*所以只用不到一个代替空间。
JamesM-SiteGen 2012年

48
不解决在线上多次出现的问题
bluesman'5

2
如果你想在子目录中搜索过这不起作用,而grep -owc -l呢。不过,在类似原始问题的情况下,cat会更快。
Leagsaidh Gordon

296

这适用于每行多次出现:

grep -o string * | wc -l

2
这也适用于:grep -o string * --exclude-dir=some/dir/one/ --exclude-dir=some/dir/two | wc -l
一位编码人员

2
grep -ioR string * | wc -l这是我用来进行不区分大小写,递归,仅匹配的搜索的方法
LeonardChallis 2015年

2
此文件显示了相关文件,然后显示了匹配的总数:grep -rc test . | awk -F: '$NF > 0 {x+=$NF; $NF=""; print} END{print "Total:",x}'
Yaron

28
grep -oh string * | wc -w

将计算一行中的多次出现


24
grep -oh "... my that curry was strong" * >> wc:)
icc97

23

而不是使用-c,只需将其通过管道传送到wc -l。

grep string * | wc -l

这将在单行中列出每次出现的次数,然后计算行数。

但是,这会丢失字符串在一行上出现2次以上的实例。


2
与“ grep -r'test'”一起使用,将管道“ wc -l”也可以很好地工作。它递归地扫描所有文件中当前目录下所有目录中的字符串“ test”。
Stevek 2011年


9

与之前的所有答案不同:

perl -lne '$count++ for m/<pattern>/g;END{print $count}' *

很高兴看到一种不使用grep的方法,尤其是因为我的grep(在Windows上)不支持-o选项。
David Roussel

9

您可以-R递归添加搜索(并避免使用cat)并-I忽略二进制文件。

grep -RIc string .

7

强制性AWK解决方案:

grep -c string * | awk 'BEGIN{FS=":"}{x+=$2}END{print x}'

但是,请注意文件名是否包含“:”。


5

AWK解决方案还处理文件名,包括冒号:

grep -c string * | sed -r 's/^.*://' | awk 'BEGIN{}{x+=$1}END{print x}'

请记住,此方法仍然无法string在同一行上找到多次。


4

如果要每个文件出现的次数(例如字符串“ tcp”):

grep -RIci "tcp" . | awk -v FS=":" -v OFS="\t" '$2>0 { print $2, $1 }' | sort -hr

输出示例:

53  ./HTTPClient/src/HTTPClient.cpp
21  ./WiFi/src/WiFiSTA.cpp
19  ./WiFi/src/ETH.cpp
13  ./WiFi/src/WiFiAP.cpp
4   ./WiFi/src/WiFiClient.cpp
4   ./HTTPClient/src/HTTPClient.h
3   ./WiFi/src/WiFiGeneric.cpp
2   ./WiFi/examples/WiFiClientBasic/WiFiClientBasic.ino
2   ./WiFiClientSecure/src/ssl_client.cpp
1   ./WiFi/src/WiFiServer.cpp

说明:

  • grep -RIci NEEDLE . -从当前目录(遵循符号链接)递归查找字符串NEEDLE,忽略二进制文件,计算出现次数,忽略大小写
  • awk ... -此命令将忽略出现次数为零的文件并设置行格式
  • sort -hr -按第一列中的数字以相反的顺序对行进行排序

当然,它也可以与其他带有选项-c(计数)的grep命令一起使用。例如:

grep -c "tcp" *.txt | awk -v FS=":" -v OFS="\t" '$2>0 { print $2, $1 }' | sort -hr

3

您可以使用简单grep的方法有效地捕获发生的次数。我将使用该-i选项来确保STRING/StrING/string被正确捕获。

提供文件名称的命令行:

grep -oci string * | grep -v :0

删除文件名并在没有文件的情况下显示0的命令行:

grep -ochi string *

您能否详细说明您的答案,并提供有关您提供的解决方案的更多说明?
abarisone 2015年


1

我使用Windows的grep测试的仅Grep解决方案:

grep -ro "pattern to find in files" "Directory to recursively search" | grep -c "pattern to find in files"

即使一行上有多个事件,此解决方案也将计算所有事件的发生。-r递归搜索目录,-o将“仅显示匹配PATTERN的行的一部分”-这是在一行上拆分多个匹配项,并使grep在新行上打印每个匹配项的原因;然后将这些换行符分隔的结果通过管道-c传递回grep中,以使用相同的模式对出现的次数进行计数。


1

这是比grep更快的AWK替代方法,该方法可处理<url>目录中XML文件集合中每行的多个匹配项:

awk '/<url>/{m=gsub("<url>","");total+=m}END{print total}' some_directory/*.xml

这在某些XML文件没有换行符的情况下效果很好。


0

另一个使用基本命令行功能的oneliner每行处理多个事件。

 cat * |sed s/string/\\\nstring\ /g |grep string |wc -l
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.