grep「+」演算子が機能しない


31

この

ls -l /var/log | awk '{print $9}' | grep "^[a-z]*\.log."

これを出力します:

alternatives.log.1
alternatives.log.10.gz
alternatives.log.2.gz
alternatives.log.3.gz
alternatives.log.4.gz
alternatives.log.5.gz
alternatives.log.6.gz
alternatives.log.7.gz
alternatives.log.8.gz
alternatives.log.9.gz
apport.log.1
apport.log.2.gz
apport.log.3.gz

でもこれは:

ls -l /var/log | awk '{print $9}' | grep "^[a-z]+\.log."

何も出力しません。

どうして?に変更*しました+。似てない?演算子+には、少なくとも1つの一致が必要で、*ゼロ以上が必要です。

回答:


36

これは、grep(引数なしで)標準の正規表現でのみ機能するためです。+拡張正規表現の一部であるため、それを使用するにはgrep -Eor を使用する必要がありますegrep

ls -l /var/log | awk '{print $9}' | grep -E "^[a-z]+\.log."

また、拡張正規表現を使用したくない場合は、これを行うことができます。

ls -l /var/log | awk '{print $9}' | grep "^[a-z][a-z]*\.log."

ありがとう。私は今、その回避策について考えていますが、なぜ「+」が機能しないのかと思っていました。今私は知っている。再度、感謝します。
マルコ

11

MiJynsの答えを詳しく説明するには、+などの「特殊文字」も標準の正規表現で機能しますが、バックスラッシュでエスケープする必要があります。あなたは、デフォルトの期待が標準と拡張正規表現の間で逆転していると言うかもしれません:

標準正規表現では、文字はデフォルトで文字通り一致します。たとえばgrep "ab+"、+はリテラルの+です。正規表現は、たとえば「ab + ab」を検索しますが、「abbbb」は検索しません。+の「特別な意味」を使用するには、エスケープする必要があります。だから、grep "ab\+"もはや「AB + AB」を「ABBB」を見つけることが、ありません。なぜなら、最後の例では、+は「1つまたは複数の」という数量詞として解釈され、その場合は「1つまたは複数のb」です。

拡張正規表現では、まったく逆です。ここでは、文字通り処理されるために「特殊文字」をエスケープする必要があります。だから、grep -E "ab+"発見"ABBB"ではなく、 "AB + AB"。+をエスケープすると、文字通り一致します。だから、grep -E "ab\+"発見"AB + AB"ではなく、 "ABBB"。


1
なんというレガシーな混乱... ;-) vimのマジックやスーパーマジックのようなもの。ほら 下位互換性のために支払う価格...
Rmano
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.