2012-09-07 13 views
6

consideran este bucle simple:Bash simple - para f * en

for f in *.{text,txt}; do echo $f; done 

Quiero hacer eco de los nombres de archivo sólo es válido. El uso de la variable $ f en un script funciona a la perfección a menos que no haya ningún archivo de esa extensión. En el caso de un conjunto vacío, $ f se establece en * .text y los ecos línea anterior:

*.text 
*.txt 

en lugar de eco nada. Esto crea un error si está tratando de usar $ f para cualquier cosa que esté esperando un nombre real de archivo real y en su lugar obtiene *.

Si hay archivos que coinciden con el comodín para que no sea un conjunto vacío todo funciona como me gustaría. p.ej.

123.text 
456.txt 
789.txt 

¿Cómo puedo hacer esto sin los errores y sin complejidad aparente excesivo de la primera cadena coincidente $ f por un asterisco I?

Respuesta

13

Establecer nullglob opt ion.

$ for f in *.foo ; do echo "$f" ; done 
*.foo 
$ shopt -s nullglob 
$ for f in *.foo ; do echo "$f" ; done 
$ 
+0

Esto es exactamente lo que estaba buscando. ¡Gracias! – user1610022

3

Puede comprobar si el archivo existe en realidad:

for f in *.{text,txt}; do if [ -f $f ]; then echo $f; fi; done 

o puede utilizar el comando find:

for f in $(find -name '*.text' -o -name '*.txt'); do 
    echo $f 
done 
+0

Probando si $ f es, de hecho, un archivo funciona bastante bien. Pero, es una prueba adicional que esperaba evitar. – user1610022

0

Además, si usted puede permitirse el uso externo de ls, se puede escapar sus resultados mediante el uso de

for f in `ls *.txt *.text`; 
+0

No funciona si los nombres de archivo contienen espacios. – choroba

+0

que se puede arreglar configurando '$ IFS' correctamente. A diferencia de la opción nullglob, esto puede ocurrir con bastante seguridad dentro de un script de shell sin llamar a shopt. – ThePadawan

+0

Por favor, muestre cómo. Además, 'shopt' es un built-in, por lo que no lo llamará" out ". – choroba