Utiliser le signe écanvas dans grep

J’essaie de rechercher la sous-chaîne “abc” dans un fichier spécifique sous linux / bash

Moi aussi:

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 pourrais-je l’accomplir en utilisant grep?

L’astérisque n’est qu’un opérateur de répétition , mais vous devez lui indiquer ce que vous répétez. /*abc*/ correspond à une chaîne contenant ab et zéro ou plus c (car 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 le dire .* – Le point signifie n’importe quel caractère ( dans certaines directives ). Si vous souhaitez simplement faire correspondre abc, vous pouvez simplement dire grep 'abc' myFile . Pour votre correspondance plus complexe, vous devez utiliser .*grep 'abc.*def' myFile correspondra à une chaîne contenant abc suivie de def avec quelque chose en option entre les deux.

Mise à jour basée sur un commentaire:

* dans une expression régulière n’est pas exactement la même 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 tous les fichiers se terminant par .log). Cependant, dans les expressions régulières, * est un modificateur, ce qui signifie qu’il ne s’applique qu’au personnage ou au groupe qui le précède. 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’écanvas, lors de la modification du point, signifie trouver un ou plusieurs points; c’est à dire. trouver un ou plusieurs de n’importe quel caractère.

Le caractère de point correspond à n’importe quel caractère, donc “. *” Signifie zéro ou plusieurs occurrences de n’importe quel caractère. Vous voulez probablement dire “. *” Plutôt que “*”.

Ah, merde,

Le signe “écanvas” 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 du shell sous Linux par exemple, s’appelle un ” glob “. Les expressions globales ne sont pas des expressions régulières complètes, ce que Grep utilise pour spécifier les chaînes à rechercher. Voici un article (ancien, petit) sur les différences. Les expressions globales (comme dans “ls *”) sont interprétées par le shell lui-même.

Il est possible de traduire des globes en RE, mais vous devez généralement le faire dans votre tête.

Vous n’utilisez pas d’expressions régulières, donc votre variante de grep choisie devrait être fgrep , qui se comportera comme prévu.

Essayez grep -E pour un support étendu des expressions régulières

Jetez également un coup d’oeil à:

La page de manuel grep

Utilisez grep -P – qui permet la prise en charge des expressions régulières de style Perl.

 grep -P "abc.*def" myfile 

C’est peut-être la réponse que vous recherchez:

 grep abc MyFile | grep def 

La seule chose est que … les lignes de sortie seront “def” avant ou après “abc”

‘*’ fonctionne comme un modificateur pour l’élément précédent. Ainsi, ‘abc * def’ recherche ‘ab’ suivi de 0 ou plus ‘c’ suivi de ‘def’.

Ce que vous voulez probablement, c’est “abc. * Def” qui recherche “abc” suivi de n’importe quel nombre de caractères, suivi de “def”.