web-dev-qa-db-ja.com

重複するパターンで機能するGrep

非常に大きなファイル内の繰り返しパターンaaの数を数えたい。したがって、次のコマンドを使用します。

grep -o "aa" ./bwt/dblp.txt | wc -l

これは、aaaなどの文字列があり、これが1つのパターンとしてのみ一致する場合を除いて機能します。私のユースケースでは、最初の2つのasが1つのパターンを意味する必要がありますが、最後の2つのasは2番目のパターンです(これは、aの中央のaaaを再利用できることを意味します)。

どうすればこれを達成できますか?

ファイルは非常に大きいので、可能であれば「最適化された」方法の方がよいことに注意してください。とにかく、どんな実用的な解決策も明らかに歓迎されています。

4
testTester

これにはPerlの正規表現が必要です。 -Pフラグをサポートするgrepの場合:

grep -oP '(?<=a)a' file | wc -l

これはポジティブです lookbehind 。これは、別のaが前に付いている単一のaと一致します。


Perlを使用する場合(またはgrep-Pフラグをサポートしていない場合):

Perl -ne 'while(m/(?<=a)a/g){$a++}END{print "$a\n"}' file

例:

$ cat file
aa
aaa
aaaa

最初の行は1つの一致、2番目の行は2つ、3番目の行はツリーである必要があります。すべて一緒に6:

$ grep -oP '(?<=a)a' file | wc -l
6
3
chaos

次のように、データファイルbig_file内の例aaのような繰り返される文字のペアを数えることができます。

tr -cs a '\012' <big_file | awk '/aa/{n += length - 1}; END {print n+0}'

線はこのように説明することができます

  • trは、a以外の文字のシーケンスを改行に変更します。これにより、aa...の複数のオカレンスが別々の行に分割されます
  • awkは、ゼロ以外の行の長さをカウントします。 N文字のシーケンスにN-1個の重複するペアが含まれるというプロパティを使用することにより、重複するペアの数を合計し、ファイルの最後に合計を生成できます。

実際、ファイルは「非常に大きい」ので、次のようにパイプラインにgrepを含めるとより良い応答が得られます。

tr -cs a '\012' <big_file | grep aa | awk '{n += length - 1}; END {print n+0}'
2
roaima