operator grep „+” nie działa

31

To

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

wyprowadza to:

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

ale to:

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

nic nie produkuje.

Czemu? Właśnie się zmieniłem *na +. Czy to nie jest podobne? Operator +potrzebuje tylko co najmniej jednego dopasowania, a *zero lub więcej.

Marko
źródło

Odpowiedzi:

36

Jest tak, ponieważ grep(bez żadnych argumentów) działa tylko ze standardowymi wyrażeniami regularnymi. +jest częścią rozszerzonych wyrażeń regularnych, więc aby z niego skorzystać, musisz użyć grep -Elub egrep:

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

Możesz to również zrobić, jeśli nie chcesz używać rozszerzonych wyrażeń regularnych:

ls -l /var/log | awk '{print $9}' | grep "^[a-z][a-z]*\.log."
MiJyn
źródło
Dzięki. Teraz omawiam to obejście, ale zastanawiałem się, dlaczego „+” nie działa. Teraz wiem. Dzięki jeszcze raz.
Marko
11

Aby rozwinąć odpowiedź MiJyns, „znaki specjalne”, takie jak +, działają również w standardowym wyrażeniu regularnym, ale musisz uciec przed nimi odwrotnym ukośnikiem. Można powiedzieć, że domyślne oczekiwania są odwrócone między standardowym i rozszerzonym wyrażeniem regularnym:

W standardowym wyrażeniu regularnym znaki domyślnie pasują dosłownie. Na przykład w grep "ab+"+ znajduje się literał +. Wyrażenie regularne znalazłoby na przykład „ab + ab”, ale nie „abbbb”. Aby użyć „specjalnego znaczenia” +, musisz uciec od niego. grep "ab\+"Znalazłbym więc „abbb”, ale już nie „ab + ab”. Ponieważ w ostatnim przykładzie znak + jest interpretowany jako kwantyfikator „jeden lub wiele z nich”, w tym przypadku „jeden lub wiele b”.

W rozszerzonym wyrażeniu regularnym jest dokładnie na odwrót. Tutaj musisz uciec od „znaków specjalnych”, aby być traktowanym dosłownie. Więc grep -E "ab+"znajduje „abbb”, ale nie „ab + ab”. Jeśli unikniesz znaku +, zostanie on dopasowany dosłownie. grep -E "ab\+"Znajduje więc „ab + ab”, ale nie „abbb”.

Henning Kockerbeck
źródło
1
Co za stary bałagan ... ;-) jak magia i supermagia w vim. Urgh. Cena do zapłaty za kompatybilność wsteczną ...
Rmano