L'opérateur grep "+" ne fonctionne pas


31

Cette

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

sort ceci:

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

mais ça:

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

ne produit rien.

Pourquoi? Je viens de changer *pour +. N'est-ce pas similaire? L'opérateur a +juste besoin d'au moins une correspondance et de *zéro ou plus.

Réponses:


36

C'est parce que grep(sans aucun argument) ne fonctionne qu'avec des expressions régulières standard. +fait partie des expressions régulières étendues, donc pour l'utiliser, vous devez utiliser grep -Eou egrep:

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

En outre, vous pouvez simplement le faire si vous ne souhaitez pas utiliser d'expressions régulières étendues:

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

Merci. Je suis maintenant sur cette solution de contournement, mais je me demandais pourquoi "+" ne fonctionne pas. Maintenant je sais. Merci encore.
Marko

11

Pour développer la réponse de MiJyns, les "caractères spéciaux" comme + fonctionnent également dans les expressions rationnelles standard, mais vous devez leur échapper avec une barre oblique inverse. Vous pourriez dire que les attentes par défaut sont inversées entre l'expression régulière et l'expression régulière:

Dans l'expression régulière, les caractères correspondent littéralement par défaut. Par exemple, dans grep "ab+"le + est un + littéral. L'expression régulière trouverait par exemple "ab + ab", mais pas "abbbb". Pour utiliser la "signification spéciale" de +, vous devez y échapper. Ainsi grep "ab\+"trouverait "abbb", mais plus "ab + ab". Parce que dans le dernier exemple, le + est interprété comme le quantificateur "un ou plusieurs de cela", dans ce cas "un ou plusieurs b".

En regex étendu, c'est exactement l'inverse. Ici, vous devez échapper aux "caractères spéciaux" pour être traité littéralement. grep -E "ab+"Trouve donc "abbb", mais pas "ab + ab". Si vous échappez au +, cela correspond littéralement. Trouve donc grep -E "ab\+""ab + ab", mais pas "abbb".


1
Quel gâchis hérité ... ;-) comme la magie et la supermagie dans vim. Urgh. Le prix à payer pour la compatibilité descendante ...
Rmano
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.