重なり合うパターンの Grep

重なり合うパターンの Grep

aa非常に大きなファイルで繰り返されるパターンの数を数えたいです。だから、次のコマンドを使用します。

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

たとえば、文字列がない場合は機能し、aaa1つのパターンにのみ一致します。私のユースケースでは、aパターンを表すために最初の2秒が必要ですが、2番目のパターンにaなるには最後の2秒が必要です(中央のaパターンをaaa再利用できることを意味します)。

この目標をどのように達成できますか?

ファイルがかなり大きいので、可能であれば、「最適化された」方法がより良いです。それにもかかわらず、実行可能なすべてのソリューションは明らかに歓迎されています。

答え1

これにはPerl正規表現が必要です。grepこのフラグをサポートするaを使用してください-P

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

これは肯定的です後ろを見て。これは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

答え2

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

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

線は次のように解釈できます。

  • tr改行文字ではなく文字シーケンスを変更しますa。これにより、複数の項目がaa...別々の行に分割されます。
  • awkゼロ以外の線の長さを計算します。 N文字シーケンスにN-1個のネストされたペアが含まれているという事実を利用して、ネストされたペアの数を追加し、ファイルの末尾に合計を生成できます。

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

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

答え3

何らかの理由でカオスの答えは私のシステム(Debian 11.5、GNU grep 3.6)には何も出力しません。他の人にも効果がある場合に備えて私に効果があった方法は次のとおりです。

pcregrep -o1 -o2 '(\w)(?=(\w))' file

これは提案されたものと精神が似ています。キャプチャグループ 2 の最初の文字の後に他の文字が続く場合は、キャプチャグループ 1 を使用して最初の文字を一致させ、将来の予測を使用して後者のみを一致させるので、まだ Can を使用できます。それを書いてください。その後、両方のグループを使用し-o1て表示します-o2

これは長さのサブシーケンスに直接一般化できますn

pcregrep -o1 -o2 '(\w)(?=(\w{n-1}))' file

答え4

grep -ow aa ./bwt/dblp.txt | wc -l

関連情報