Utilisation du signe étoile dans grep
J'essaie de rechercher la sous-chaîne " abc " dans un fichier spécifique dans linux / bash
Donc je fais:
grep '*abc*' myFile
Il ne retourne rien.
Mais si je le fais:
grep 'abc' myFile
Il renvoie les correspondances correctement.
Maintenant, ce n'est pas un problème pour moi. Mais que faire si je veux grep pour une chaîne plus complexe, disons
*abc * def *
Comment l'accomplir en utilisant grep?
10 réponses
L'astérisque est juste un opérateur de répétition , mais vous devez lui dire ce que vous répétez. /*abc*/
correspond à une chaîne contenant ab et zéro ou plus de c (parce que le second * est sur le c; le premier n'a pas de sens car il n'y a rien à répéter). Si vous voulez faire correspondre quelque chose, vous devez dire .*
-- le point signifie n'importe quel caractère (dans certaines lignes directrices). Si vous voulez juste faire correspondre abc, vous pouvez simplement dire grep 'abc' myFile
. Pour votre correspondance plus complexe, vous devez utiliser .*
-- {[4] } correspondra à une chaîne qui contient abc suivi de def avec quelque chose éventuellement entre les deux.
Mise à Jour basé sur un commentaire:
*
dans une expression régulière n'est pas exactement la même chose que * dans la console. Dans la console, * fait partie d'une construction glob, et agit simplement comme un caractère générique (par exemple ls *.log
listera tous les fichiers qui se terminent par .journal). Cependant, dans les expressions régulières, * est un modificateur, ce qui signifie qu'il ne s'applique qu'au caractère ou au groupe le précédant. Si vous voulez que * dans les expressions régulières agisse comme un caractère générique, vous devez utiliser .*
comme mentionné précédemment - le point est un caractère générique, et l'étoile, lors de la modification du point, signifie Trouver un ou plusieurs points; ie. trouver un ou plusieurs de n'importe quel caractère.
Le caractère dot signifie correspondre à n'importe quel caractère, donc '.* "signifie zéro ou plusieurs occurrences de tout caractère. Tu veux sans doute dire à utiliser.* 'plutôt que juste'*'.
Ah, Merde,
Le "signe d'étoile" n'a de sens que s'il y a quelque chose devant lui. S'il n'y a pas l'outil (grep dans ce cas) peut simplement le traiter comme une erreur. Par exemple:
'*xyz' is meaningless
'a*xyz' means zero or more occurrences of 'a' followed by xyz
L'expression que vous avez essayée, comme celles qui fonctionnent sur la ligne de commande shell sous Linux par exemple, s'appelle "glob ". Les expressions Glob ne sont pas complètes Les expressions régulières, ce que grep utilise pour spécifier les chaînes à rechercher. Ici est (vieux, petit) post sur les différences. Les expressions glob (comme dans "ls *") sont interprétées par le shell lui-même.
Il est possible de traduire des globs en REs, mais vous devez généralement le faire dans votre tête.
Vous n'utilisez pas d'expressions régulières, donc votre variante grep de choix devrait être fgrep
, qui se comportera comme vous l'attendez.
Utilisez grep - P-qui permet la prise en charge des expressions régulières de style Perl.
grep -P "abc.*def" myfile
Essayez grep-E pour la prise en charge des expressions régulières étendues
Jetez également un oeil à:
Cela peut être la réponse que vous cherchez:
grep abc MyFile | grep def
La seule chose est... il va sortir les lignes étaient "def" est avant ou après " abc "
'*' fonctionne comme un modificateur pour l'élément précédent. Donc, 'abc * def' recherche 'ab' suivi de 0 ou plus 'c' suivi de 'def'.
Ce que vous voulez probablement est ' abc.* def 'qui recherche' abc 'suivi d'un nombre quelconque de caractères, suivi de 'def'.
Cela a fonctionné pour moi:
Grep ".* ${expr} " - avec des guillemets doubles, précédés du point, grep standard sans commutateurs supplémentaires.