grep -c
ファイル内の特定の文字列が表示される回数を見つけるのに役立ちますが、各発生は1行に1回だけカウントされます。各行で複数回発生する回数を計算する方法は?
私は次よりもエレガントなものを探しています。
perl -e '$_ = <>; print scalar ( () = m/needle/g ), "\n"'
答え1
grepは-o
一致するものだけを出力し、行を無視しますwc
。
grep -o 'needle' file | wc -l
これは「needles」または「multineedle」とも一致します。
単一の単語のみを一致させるには、次のいずれかのコマンドを使用します。
grep -ow 'needle' file | wc -l
grep -o '\bneedle\b' file | wc -l
grep -o '\<needle\>' file | wc -l
答え2
GNU grep(常にLinuxとCygwinで、時には他の場所で)がある場合は、次のことができます。出力ライン数の計算grep -o
:grep -o needle | wc -l
。
Perlの場合、次のアプローチがあなたのアプローチよりもエレガントであることがわかりました。安定)。
perl -lne 'END {print $c} map ++$c, /needle/g'
perl -lne 'END {print $c} $c += s/needle//g'
perl -lne 'END {print $c} ++$c while /needle/g'
POSIXツールのみを使用する場合の1つのアプローチ(可能な場合)は、入力をgrepに渡す前に個々の一致がある行に分割することです。たとえば、単語全体を見つけるには、まず単語ではなく各文字を改行文字に変換します。
# equivalent to grep -ow 'needle' | wc -l
tr -c '[:alnum:]' '[\n*]' | grep -c '^needle$'
それ以外の場合は、この特定のテキスト処理を実行する標準コマンドがないため、sed(マゾヒストの場合)またはawkに切り替える必要があります。
awk '{while (match($0, /set/)) {++c; $0=substr($0, RSTART+RLENGTH)}}
END {print c}'
sed -n -e 's/set/\n&\n/g' -e 's/^/\n/' -e 's/$/\n/' \
-e 's/\n[^\n]*\n/\n/g' -e 's/^\n//' -e 's/\n$//' \
-e '/./p' | wc -l
以下は、文字列と正規表現の両方で機能しますが、アンカーパターンがあるいくつかの特殊なケースでは失敗するsed
andを使用するより簡単なソリューションです(たとえば、またはで2回発生するものを探します)。grep
^needle
\bneedle
needleneedle
sed 's/needle/\n&\n/g' | grep -cx 'needle'
上記の sed 置換では\n
改行文字を参照しています。これはパターン部分では標準ですが、代替テキストでは移植性のためにバックスラッシュ改行文字に置き換えられます\n
。
答え3
私のように、実際には「両方、それぞれ正確に1回」(実際には「2つのうち1つ、2回」)が必要な場合は簡単です。
grep -E "thing1|thing2" -c
出力を確認してください2
。
このアプローチの利点(正確に一度の場合)はいあなたが望むのは簡単にスケーラブルであるということです。
答え4
これを行う必要がありますが、複数のクエリに対して実行する必要があります。列にリストし、各列の発生回数をリストしたいと思います。
私のbash専用の1行の解決策は次のとおりです。
grep -o -E 'borp|flarb' flarb.log | sort | uniq -c
910 borp
9090 flarb