Jobserve le comportement suivant de grep
lors de son exécution cinq fois:
me@asus:~/go/src/company/topology-front$ lsof |grep "READ" vim 4788 me 4u REG 8,2 12288 32247694 /home/me/go/src/company/topology-front/.README.md.swp me@asus:~/go/src/company/topology-front$ lsof |grep "README.md*" vim 4788 me 4u REG 8,2 12288 32247694 /home/me/go/src/company/topology-front/.README.md.swp me@asus:~/go/src/company/topology-front$ lsof |grep "README.md" vim 4788 me 4u REG 8,2 12288 32247694 /home/me/go/src/company/topology-front/.README.md.swp me@asus:~/go/src/company/topology-front$ lsof |grep "*README.md*" me@asus:~/go/src/company/topology-front$ lsof |grep "*README.md" me@asus:~/go/src/company/topology-front$
Je ne pouvais pas comprendre pourquoi les deux derniers essais de grep
ne retournent aucun résultat .
Réponse
grep
les modèles sont des expressions régulières (alias regex, regexp, RE), expressions régulières basiques (BRE) sauf si lune des -E
/ -F
/ -P
/ -K
/ -X
loption (dont seuls les deux premiers étant standard) est utilisée.
*
est un opérateur dexpression régulière qui correspond à 0 ou plus de l atome précédent. Par exemple, d*
correspond à 0 ou plus d
s. Dans les BRE, au début du modèle ou en suivant le
ou \(
opérateurs dexpression régulière, il correspond à un littéral *
uniquement (il « est également pris littéralement à lintérieur de [...]
expressions entre crochets).
Donc grep "*README.md*"
correspond aux lignes qui contiennent un littéral *
suivi de README
suivi dun seul caractère (lopérateur .
regexp) suivi de m
suivi dun nombre quelconque de d
s. Puisque nimporte quel nombre inclut 0, cela « est fonctionnellement équivalent à grep "*README.m"
(ce qui ne ferait aucune différence avec quelles lignes sont mises en correspondance, uniquement sur ce qui peut être mis en correspondance dans la ligne (qui apparaîtrait avec loption --color
de GNU grep
par exemple)).
Par exemple , il correspondrait sur ces 2 lignes:
*README mike ^^^^^^^^^ DONT***README-mddd ^^^^^^^^^^^^
(les ^
montrent ce qui correspond dans la ligne par lexpression régulière, que vous pouvez voir avec --color
)
Ici, il semble que vous « confondez les expressions régulières avec les motifs génériques du shell. Lopérateur générique *
qui correspond à 0 ou plusieurs caractères peut être écrit .*
dans des expressions régulières. Mais faire:
grep ".*README\.md.*"
serait à nouveau la même chose que:
grep "README\.md"
Comme grep
recherche une correspondance dans la ligne au lieu de trouver des lignes qui correspondent exactement au modèle (pour lequel vous avez besoin de -x
).
Avec ast-open grep
, qui est également ksh93
« s grep
builtin (pas toujours intégré par défaut, et vous devez lactiver en mettant /opt/ast/bin
avant $PATH
), vous pouvez utiliser loption -K
pour grep
pour utiliser des caractères génériques shell (étendus ksh93). Donc avec cela grep
implémentation, vous pouvez faire:
grep -K "README.md"
ou
grep -xK "*README.md*"
pour faire correspondre les lignes contenant README.md
.
Avec cette même implémentation, la correspondance générique peut également être activée dans Extended (), augmenté (-X
) ou de type perl (-P
) régulier expressions avec lopérateur (?K)
(et \(?K\)
dans les expressions régulières de base qui cassent réellement la conformité POSIX, donc je ne me fierais pas pourrait être supprimé dans une version future). Vous pouvez donc faire:
grep -xE "(?K)*README.md*"
ici.
Avec toute implémentation grep
moderne, vous pouvez également faire:
grep -F README.md
Pour une recherche à chaîne fixe (où .
ci-dessus correspond à un littéral .
au lieu de nimporte quel caractère).
*
ou+
au début de lexpression régulière, tout commegrep -P
grep -E
avec plusieurs implémentations. Ce*
traité littéralement au début nest spécifié que pour les BRE. Avec dautres RE, YMMV.grep
(ougrep -G
).grep -K
qui utilise des modèles de shell (où*
correspond à nimporte quel nombre de caractères).*
nest pas spécial lorsque le premier caractère dun BRE, voir la spécification POSIX