2010-11-29 14 views
10

Dans Bash, comment faire correspondre une expression régulière avec plusieurs critères à un nom de fichier? Par exemple, je voudrais faire correspondre tous les fichiers avec les terminaisons .txt ou .log.Expressions régulières pour le nom de fichier correspondant

Je sais comment faire correspondre un type de critères:

for file in *.log 
do 
     echo "${file}" 
done 

Quelle est la syntaxe d'une logique ou pour correspondre à deux ou plusieurs types de critères?

Répondre

14

Procédez de la même manière que vous appelez ls. Vous pouvez spécifier plusieurs jokers l'un après l'autre:

for file in *.log *.txt 
+0

Fonctionne principalement, mais la seule chose étrange est que lorsque je n'ai pas de fichiers. Txt, ". Txt" est écho. – Mike

+2

@Mike vous devez définir l'option shell nullglob en utilisant le shopt builting pour éviter cela – thkala

+0

Merci @thkala! – Mike

1
for f in $(find . -regex ".*\.log") 
do 
    echo $f 
end 
+3

Celui-ci va rompre avec les espaces dans les noms de fichiers ... – thkala

+0

La regex est comparée au chemin complet y compris les répertoires. – Albert

8
for file in *.{log,txt} .. 
3

Vous ajoutez simplement les autres conditions à la fin:

for VARIABLE in 1 2 3 4 5 .. N 
do 
    command1 
    command2 
    commandN 
done 

Donc dans votre cas:

for file in *.log *.txt 
do 
     echo "${file}" 
done 
17

Bash ne prend pas en charge les expressions régulières en tant que globbing (filena moi correspondant). Sa syntaxe de globbing, cependant, peut être assez polyvalente. Par exemple:

for i in A*B.{log,txt,r[a-z][0-9],c*} Z[0-5].c; do 
... 
done 

appliquera le contenu en boucle sur tous les fichiers qui commencent par A et se terminer par un B, un point et l'une des extensions suivantes:

  • journal
  • txt
  • r suivi d'une lettre minuscule suivie d'un chiffre
  • c suivi assez grand chose

Il appliquera également les commandes de boucle à un fichier commençant par Z, suivi d'un chiffre dans la plage 0-5, puis de l'extension .c.

Si vous voulez vraiment/besoin, vous pouvez activer étendu englobement avec la commande interne shopt:

shopt -s extglob 

qui permet alors des fonctionnalités beaucoup plus en noms de fichiers contenant, comme des sous-modèles, etc.

consultez le manuel de Bash pour plus d'informations sur les expressions prises en charge:

http://www.gnu.org/software/bash/manual/bash.html#Pattern-Matching

EDIT:

Si une expression ne correspond pas à un nom de fichier, bash par défaut remplacera l'expression elle-même (par ex. il fera écho * .txt) plutôt qu'une chaîne vide. Vous pouvez modifier ce comportement en définissant l'option shell nullglob:

shopt -s nullglob 

Cela remplacera un fichier .txt de * qui n'a pas les fichiers correspondants une chaîne vide.

EDIT 2:

Je vous suggère de vérifier également les shopt BUILTIN et ses options, depuis un certain nombre d'entre elles affectent pattern matching nom de fichier, ainsi que d'autres aspects du shell:

http://www.gnu.org/software/bash/manual/bash.html#The-Shopt-Builtin

3

Vous pouvez aussi le faire:

shopt -s extglob 
for file in *.+(log|txt) 

qui pourrait facilement être étendu à d'autres alternatives:

for file in *.+(log|txt|mp3|gif|foo)