O operador grep “+” não funciona

31

este

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

gera isso:

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

mas isso:

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

não produz nada.

Por quê? Acabei de mudar *para +. Não é semelhante? O operador +precisa apenas de pelo menos uma correspondência e *zero ou mais.

Marko
fonte

Respostas:

36

Isso ocorre grep(sem argumentos) funciona apenas com expressões regulares padrão. +faz parte das expressões regulares estendidas; portanto, para usar isso, você precisa usar grep -Eou egrep:

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

Além disso, você pode fazer isso se não quiser usar expressões regulares estendidas:

ls -l /var/log | awk '{print $9}' | grep "^[a-z][a-z]*\.log."
MiJyn
fonte
Obrigado. Eu agora sobre essa solução alternativa, mas eu queria saber por que "+" não funciona. Agora eu sei. Obrigado novamente.
Marko
11

Para elaborar a resposta do MiJyns, "caracteres especiais" como + funcionam também na regex padrão, mas você precisa escapar deles com uma barra invertida. Você pode dizer que as expectativas padrão são revertidas entre regex padrão e estendido:

Na regex padrão, os caracteres correspondem literalmente por padrão. Por exemplo, no grep "ab+"+ é um + literal. O regex, por exemplo, encontraria "ab + ab", mas não "abbbb". Para usar o "significado especial" de +, você precisa escapar dele. Então grep "ab\+", encontraria "abbb", mas não "ab + ab" por mais tempo. Como no último exemplo, o + é interpretado como o quantificador "um ou muitos disso", nesse caso "um ou muitos b".

No regex estendido, é exatamente o contrário. Aqui, você precisa escapar de "caracteres especiais" para ser tratado literalmente. Então grep -E "ab+"encontra "abbb", mas não "ab + ab". Se você escapar do +, ele será correspondido literalmente. Então grep -E "ab\+"encontra "ab + ab", mas não "abbb".

Henning Kockerbeck
fonte
1
Que bagunça herdada ... ;-) como mágica e supermagia no vim. Urgh. O preço a pagar pela compatibilidade com versões anteriores ...
Rmano