2回grepする方法は?

2回grepする方法は?
[user@notebook ~]$ printf 'adgaa alpha lajsd assa ><>4 saf\n63SXYZae fkrk safXYZek\nsaf betf!%saa sDGFXYZFalf\n'
adgaa alpha lajsd assa ><>4 saf
63SXYZae fkrk safXYZek
saf betf!aa sDGFXYZFalf
[user@notebook ~]$ 
[user@notebook ~]$ printf 'adgaa alpha lajsd assa ><>4 saf\n63SXYZae fkrk safXYZek\nsaf betf!%saa sDGFXYZFalf\n' | grep SOMEMAGIC
63SXYZae fkrk safXYZek
[user@notebook ~]$ 

質問:与えられた文字列が2回ある行だけを見つけるためにgrepする方法は?この例では、文字列は「XYZ」です。 2つの文字列の間には何でも構いません。

答え1

二度グレッピングしても無駄はありません。あなたのニーズに合った正規表現と一緒にegrepを使用することを選択します。

ps ax | egrep '(a.*){2}'

これにより、「a」が2回あるすべてのプロセスが提供されます。もちろん、egrepが読めるすべてのタイプの入力に使用できます。

答え2

正規表現を使用すると、次のことができます。逆参照グループ化(パターン)または一致が{繰り返されることを指定できます}。 2つの違いは重要です。簡単な例として文字列を考えてみましょう。

baa

...次のパターンがすべて一致する場合:

\([ba]\)\{2\}
\([ba]\)\1

最初のケースでは、パターンは単一の文字を検索するため、グループ化は実際には関係ありません。反復を指定するときのグループ化の唯一の重要な点は、反復が参照できる完全なサブ式を含めることができることです。したがって、この簡単な例では...

 [ba]\{2\}

...そして...

\([ba]\)\{2\}

...同義語であり、一致エンジンが2文字の入力から最も左側にある最も長い文字列を見つける必要があることを理解することができます。第二または。繰り返し適用対象模様これは作るマッチそしていいえ大会内容に。文字通り、次のことを意味します。

[ba][ba]

....同じ方法で...

\(a.*\)\{2\}

...方法...

a.*a.*

...これは単一の文字に対してうまく機能します。しかし、これは一致する文字列を再一致させる方法の良い例ではありません。

入力サンプルの場合、これは次のようになります。

ba

しかし、逆参照は非常に異なります。公募内容。簡単な例ケース...

aa

...これは、入力の左端にある最も長い文字列であり、サブ式のパターンと一致する文字で構成され、[ba]すぐ後ろに続くためです。それ自体- 文字に一致するパターンではありません。

だからあなたは以下が欲しい:

\(pattern\).*\1

正規表現なので模様そして一致する文字列は同じではありません。それ以外の場合、当初は正規表現を使用する呼び出しはあまりありません。少し複雑な入力の例で違いを示すには、次の点を考慮してください。

printf %s\\n 123ABC321 123ABC123 321ABC321 |
grep '\([123]\{3\}.*\)\{2\}'

上記の内容は次のようgrepに印刷されます。

123ABC321
123ABC123
321ABC321

...なぜなら、すべての場合に模様試合は2回成功しました。ただし、そのgrep行が次に置き換えられた場合:

grep '\([123]\{3\}\).*\1'

...ただ印刷されます...

123ABC123
321ABC321

関連情報