2010-11-29 14 views
10

En Bash, ¿cómo se puede hacer coincidir una expresión regular con múltiples criterios con un nombre de archivo? Por ejemplo, me gustaría hacer coincidir todos los archivos con terminaciones .txt o .log.Expresiones regulares para la coincidencia de nombre de archivo

sé cómo hacer coincidir un tipo de criterios:

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

¿Cuál es la sintaxis de una lógica o para que coincida con dos o más tipos de criterios?

Respuesta

14

Hazlo de la misma manera que invocarías ls. Puede especificar varios comodines uno tras otro:

for file in *.log *.txt 
+0

Parcialmente funciona, pero la única cosa rara es que cuando no tengo los archivos .txt, ".txt" se echo'ed. – Mike

+2

@Mike necesita establecer la opción de shell nullglob utilizando el bucket de shopt para evitar esto – thkala

+0

¡Gracias @thkala! – Mike

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

Éste se dividirá con espacios en blanco en nombres de archivos ... – thkala

+0

La expresión regular se compara con la ruta completa, incluidos los directorios. – Albert

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

Usted sólo tiene que añadir otras condiciones hasta el final:

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

Así, en su caso:

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

Bash no es compatible con expresiones regulares per se cuando se aplica globbing (filena yo juego). Su sintaxis globbing, sin embargo, puede ser bastante versátil. Por ejemplo:

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

se aplicarán los contenidos de bucle en todos los archivos que comienzan con A y terminar en un B, a continuación, un punto y cualquiera de las siguientes extensiones:

  • registro
  • txt
  • r seguido por una letra minúscula seguida de un solo dígito
  • c seguido por casi cualquier cosa

También aplicará los comandos de bucle a un archivo que empiece por Z, seguido por un dígito en el rango 0-5 y luego por la extensión .c.

Si realmente quiere/necesita, puede permitir englobamiento extendido con la orden interna shopt:

shopt -s extglob 

que a su vez permite significativamente más características mientras que empareja nombres de archivo, tales como sub-patrones etc.

consulte el manual de Bash para obtener más información sobre las expresiones compatibles:

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

EDIT:

Si una expresión no coincide con un nombre de archivo, bash sustituirá la expresión por sí misma (p. Ej. se repetirá * .txt) en lugar de una cadena vacía. Puede cambiar este comportamiento estableciendo la opción del shell nullglob:

shopt -s nullglob 

Esto reemplazará un archivo .txt * que no tiene archivos que coinciden con una cadena vacía.

EDIT 2:

le sugiero que también echa un vistazo a los shopt incorporadas y sus opciones, ya que un buen número de ellos afectan la igualación de nombre de archivo de patrón, así como otros aspectos de la la cáscara:

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

3

también puede hacer esto:

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

que podría extenderse fácilmente a más alternativas:

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