ファイル内のパターンの出現回数をカウントします(同じ行でも)


94

ファイル内の文字列の出現回数を検索するときは、通常、次のように使用します。

grep pattern file | wc -l

ただし、grepの動作方法が原因で、1行に1つしか見つかりません。文字列が同じ行にあるか異なる行にあるかに関係なく、文字列がファイルに出現する回数を検索するにはどうすればよいですか?

また、単純な文字列ではなく正規表現パターンを検索している場合はどうなりますか?どうすればそれらを数えることができますか、またはさらに良いことに、各一致を新しい行に印刷できますか?

回答:


156

すべての発生をカウントするには、を使用します-o。これを試して:

echo afoobarfoobar | grep -o foo | wc -l

そしてman grepもちろん(:

更新

grep -co foo代わりに使用することを提案する人もいますgrep -o foo | wc -l

しないでください。

このショートカットは、すべての場合で機能するわけではありません。マンページは言う:

-c print a count of matching lines

これらのアプローチの違いを以下に示します。

1。

$ echo afoobarfoobar | grep -oc foo
1

a{foo}barfoobar一致が見つかるすぐに検索が停止します。1行だけがチェックされ、一致したため、出力は1です。実際に-oはここでは無視され、grep -c代わりに使用できます。

2。

$ echo afoobarfoobar | grep -o foo
foo
foo

$ echo afoobarfoobar | grep -o foo | wc -l
2

a{foo}bar{foo}barすべての出現-o)を見つけるように明示的に要求したため、行()で2つの一致が見つかりました。すべての発生は別の行にwc -l出力され、出力の行数を数えるだけです。


1
うわー...それは本当にそんなに簡単ですか?
jrdioko、2010年

1
この場合、grep -ocは機能しません。echo afoobarfoobar | grep -oc foo
Paulus

複数のファイルに対してこれを行う方法はありませんか?たとえば、一連のファイルでファイルごとの発生数を確認するとします。grep -c * を使用して行ごとに実行できますが、インスタンスごとには実行できません。
キー

grep -o foo a.txt b.txt | sort | uniq -cうまく機能します(GNU grepを使用):gist.github.com/hudolejev/81a05791f38cbacfd4de3ee3b44eb4f8
hudolejev

2

これを試して:

grep "string to search for" FileNameToSearch | cut -d ":" -f 4 | sort -n | uniq -c

サンプル:

grep "SMTP connect from unknown" maillog | cut -d ":" -f 4 | sort -n | uniq -c
  6  SMTP connect from unknown [188.190.118.90]
 54  SMTP connect from unknown [62.193.131.114]
  3  SMTP connect from unknown [91.222.51.253]

1

遅れた投稿:
検索の正規表現パターンをレコードセパレーター(RS)として使用するawk
これにより、正規表現を複数の\n行で区切ることができます(必要な場合)。

printf 'X \n moo X\n XX\n' | 
   awk -vRS='X[^X]*X' 'END{print (NR<2?0:NR-1)}'

0

grepの高速代替手段であるRipgrepは、バージョン0.9で一致--count-matchesをカウントできるフラグを導入しました(一貫性を保つために上記の例を使用しています)。

> echo afoobarfoobar | rg --count foo
1
> echo afoobarfoobar | rg --count-matches foo
2

OPからの質問のとおり、ripgrepでは正規表現パターンも使用できます(--regexp <PATTERN>)。また、各(行)の一致を別の行に出力することもできます。

> echo -e "line1foo\nline2afoobarfoobar" | rg foo
line1foo
line2afoobarfoobar

-1

grepのcolor関数をハックし、出力するカラータグの数を数えます。

echo -e "a\nb  b b\nc\ndef\nb e brb\nr" \
| GREP_COLOR="033" grep --color=always  b \
| perl -e 'undef $/; $_=<>; s/\n//g; s/\x1b\x5b\x30\x33\x33/\n/g; print $_' \
| wc -l
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.