91 votes

utiliser l'expression régulière si la condition d'en bash

Je me demande la règle générale, pour utiliser une expression régulière si la clause en bash?

Voici un exemple

$ gg=svm-grid-ch  
$ if [[ $gg == *grid* ]] ; then echo $gg; fi  
svm-grid-ch  
$ if [[ $gg == ^....grid* ]] ; then echo $gg; fi  
$ if [[ $gg == ....grid* ]] ; then echo $gg; fi  
$ if [[ $gg == s...grid* ]] ; then echo $gg; fi  
$   

Pourquoi les trois derniers ne parvient pas à égaler?

J'espère que vous pourrait donner autant de règles générales que possible, non seulement pour cet exemple.

133voto

Dennis Williamson Points 105818

Lors de l'utilisation d'un glob modèle, un point d'interrogation représente un caractère unique et un astérisque représente une séquence de zéro ou plus caractères:

if [[ $gg == ????grid* ]] ; then echo $gg; fi

Lors de l'utilisation d'une expression régulière, un point représente un caractère unique et un astérisque représente zéro ou plusieurs caractères précédents. Donc,".*" représente zéro ou plus de n'importe quel caractère, "a*" représente zéro ou plus "un", "[0-9]*" représente zéro ou plus de chiffres. Uns (parmi plusieurs) est le signe qui représente un ou plusieurs caractères précédents. Donc,"[a-z]+" représente un ou plusieurs minuscules caractère alpha (dans la locale C - et de quelques autres).

if [[ $gg =~ ^....grid.*$ ]] ; then echo $gg; fi

37voto

Enrico Carlesso Points 3182

Utilisation =~

pour l'expression régulière vérifier http://www.regular-expressions.info/tutorialcnt.html

15voto

if [[ $gg =~ ^....grid.* ]]

9voto

vladr Points 34562

L'ajout de cette solution avec grep et de base sh objets internes pour ceux intéressés par plus de solution portable (indépendant de l' bash version; fonctionne également avec la plaine vieux - sh, sur la non-plates-formes Linux, etc.)

# GLOB matching
gg=svm-grid-ch    
case "$gg" in
   *grid*) echo $gg ;;
esac

# REGEXP    
if echo "$gg" | grep '^....grid*' >/dev/null ; then echo $gg ; fi    
if echo "$gg" | grep '....grid*' >/dev/null ; then echo $gg ; fi    
if echo "$gg" | grep 's...grid*' >/dev/null ; then echo $gg ; fi    

# Extended REGEXP
if echo "$gg" | egrep '(^....grid*|....grid*|s...grid*)' >/dev/null ; then
  echo $gg
fi    

Quelques - grep incarnations également en charge l' -q (calme) option comme une alternative à la redirection d' /dev/null, mais la redirection est de nouveau le plus portable.

4voto

ghostdog74 Points 86060

@OP,

Is glob pettern not only used for file names?

Non, "glob" modèle n'est pas seulement utilisé pour les noms de fichier. vous l'utiliser pour comparer des chaînes ainsi. Dans votre exemple, vous pouvez utiliser cas/esac pour rechercher des chaînes de motifs.

 gg=svm-grid-ch 
 # looking for the word "grid" in the string $gg
 case "$gg" in
    *grid* ) echo "found";;
 esac

 # [[ $gg =~ ^....grid* ]]
 case "$gg" in ????grid*) echo "found";; esac 

 # [[ $gg =~ s...grid* ]]
 case "$gg" in s???grid*) echo "found";; esac

In bash, when to use glob pattern and when to use regular expression? Thanks!

Les Regex sont plus souples et plus "pratique" que "glob modèles", cependant, sauf si vous faites des tâches complexes que "globbing/étendue d'expansion" ne peut pas fournir facilement, alors il n'y a pas besoin d'utiliser des regex. Regex ne sont pas pris en charge pour la version de bash <3.2 (comme dennis mentionné), mais vous pouvez toujours l'utilisation prolongée d'expansion (en définissant extglob ). pour les étendues d'expansion, voir ici et la quelques exemples simples ici.

Mise à jour pour l'OP: Exemple de trouver les fichiers qui commencent par 2 caractères (les points "." signifie 1 char), suivie par "g" utilisation des regex

par exemple sortie

$ shopt -s dotglob
$ ls -1 *
abg
degree
..g

$ for file in *; do [[ $file =~ "..g" ]] && echo $file ; done
abg
degree
..g

Ci-dessus, les fichiers sont comparés parce que leurs noms contiennent 2 caractères suivis de "g". (ie ..g).

L'équivalent avec d'expansion sera quelque chose comme ceci: (voir référence pour le sens de l' ? et * )

$ for file in ??g*; do echo $file; done
abg
degree
..g

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X