Der grep “+” Operator funktioniert nicht

31

Dies

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

gibt dies aus:

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

aber dieses:

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

gibt nichts aus.

Warum? Ich habe gerade geändert *zu +. Ist es nicht ähnlich? Der Operator +benötigt nur mindestens eine Übereinstimmung und *null oder mehr.

Marko
quelle

Antworten:

36

Dies liegt daran, dass grep(ohne Argumente) nur mit regulären Standardausdrücken funktioniert. +Teil der erweiterten regulären Ausdrücken ist, so dass zu verwenden, müssen Sie verwenden grep -Eoder egrep:

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

Sie können dies auch tun, wenn Sie keine erweiterten regulären Ausdrücke verwenden möchten:

ls -l /var/log | awk '{print $9}' | grep "^[a-z][a-z]*\.log."
MiJyn
quelle
Vielen Dank. Ich habe jetzt über diese Problemumgehung nachgedacht, aber ich habe mich gefragt, warum "+" nicht funktioniert. Jetzt weiß ich. Danke noch einmal.
Marko
11

Um MiJyns Antwort zu erläutern, funktionieren "Sonderzeichen" wie + auch in regulärem Regex, aber Sie müssen sie mit einem Backslash umgehen. Man könnte sagen, dass die Standarderwartungen zwischen Standard- und erweitertem regulären Ausdruck umgekehrt sind:

In Standard-Regex stimmen Zeichen standardmäßig buchstäblich überein. Zum Beispiel ist im grep "ab+"+ ein wörtliches +. Der Regex würde zum Beispiel "ab + ab" finden, aber nicht "abbbb". Um die "spezielle Bedeutung" von + zu verwenden, müssen Sie sie maskieren. Also grep "ab\+"würde "abbb" finden, aber nicht mehr "ab + ab". Weil im letzten Beispiel das + als der Quantifizierer "eins oder viele davon" interpretiert wird, in diesem Fall "eins oder viele b".

In Extended Regex ist es genau umgekehrt. Hier müssen Sie "Sonderzeichen" entkommen, um buchstäblich behandelt zu werden. So grep -E "ab+"findet "abbb", aber nicht "ab + ab". Wenn Sie dem + entkommen, wird es buchstäblich abgeglichen. So grep -E "ab\+"findet "ab + ab", aber nicht "abbb".

Henning Kockerbeck
quelle
1
Was für ein Vermächtnis-Durcheinander ... ;-) wie Magie und Supermagie in vim. Urgh. Der Preis für die Abwärtskompatibilität zu zahlen ...
Rmano