316

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

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。)

4

16 回答 16

313

这适用于每行多次出现:

grep -o string * | wc -l
于 2010-07-14T19:31:55.687 回答
298
cat * | grep -c string
于 2008-12-16T12:17:21.993 回答
29
grep -oh string * | wc -w

将计算一行中的多次出现

于 2013-02-27T07:40:33.363 回答
26

不要使用 -c,只需将其通过管道传递给 wc -l。

grep string * | wc -l

这将在一行中列出每个出现,然后计算行数。

但是,这将错过字符串在一行上出现 2 次以上的情况。

于 2008-12-16T12:15:58.377 回答
18
cat * | grep -c string

的罕见有用的应用程序之一cat

于 2008-12-16T12:18:14.347 回答
13

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

grep -RIc string .
于 2013-12-12T12:18:30.357 回答
12

与之前所有答案不同的东西:

perl -lne '$count++ for m/<pattern>/g;END{print $count}' *
于 2013-02-27T08:00:26.510 回答
10

强制 AWK 解决方案:

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

请注意您的文件名是否包含“:”。

于 2011-09-29T12:26:37.380 回答
7

AWK 解决方案还可以处理包括冒号在内的文件名:

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

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

于 2013-01-25T20:07:35.510 回答
6

如果您想要每个文件的出现次数(例如字符串“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
于 2018-04-30T15:35:07.083 回答
5

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

给出文件名的命令行:

grep -oci string * | grep -v :0

如果有一个文件没有出现,则删除文件名并打印 0 的命令行:

grep -ochi string *
于 2015-06-12T13:19:38.037 回答
4

递归变体:

find . -type f -exec cat {} + | grep -c 'string'
于 2017-07-17T16:25:39.247 回答
2

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

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

这适用于某些 XML 文件没有换行符的情况。

于 2014-06-11T19:02:34.820 回答
2

我用 grep for windows 测试的 Grep 唯一解决方案:

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

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

于 2015-12-15T19:05:18.033 回答
0

另一个使用基本命令行函数处理每行多次出现的单行器。

 cat * |sed s/string/\\\nstring\ /g |grep string |wc -l
于 2014-01-23T16:26:55.803 回答
0
awk -v RS='' -v FPAT='fast' '{print NF,FILENAME}' <file1..N>

取一个字符串,使其成为一个快速的实例,然后打印带有文件名的字段数。

于 2021-09-13T20:47:57.593 回答