2012-02-04 43 views
6

utilizo el siguiente script de Bash para listar los archivos ".txt" de forma recursiva en el directorio actual:Bash Shell archivos de lista utilizando bucle "for"

#!/bin/bash 
for file in $(find . -type f -name "*.txt") 
do 
    echo $file 
    # Do something else. 
done 

Sin embargo, algunos de los archivos ".txt" bajo el directorio actual tienen espacios en sus nombres, por ejemplo "mi prueba.txt". La lista se corrompe, p. "Mi testing.txt" aparece como

my 
testing.txt 

Parece que el bucle "for" utiliza "espacio en blanco" (espacio, \ n etc) para separar la lista de archivos, pero en mi caso quiero usar solamente "\ n" para separar la lista de archivos.

¿Hay alguna manera en que pueda modificar este script para lograr este propósito? Alguna idea.

Gracias de antemano.

+0

En bash, creo que usas 'find ... -print0' y' IFS = "\ 0" ', o menos. Definitivamente hay otras preguntas sobre este tema. –

Respuesta

7

Si está utilizando fiesta de 4, sólo tiene que utilizar un pegote:

#!/bin/bash                  

shopt -s globstar 

for file in **/*.txt 
do 
    if [[ ! -f "$file" ]] 
    then 
     continue 
    fi 
    echo "$file" 
    # Do something else.               
done 

Asegúrese de citar "$file" o tendrá que tener el mismo problema en otros lugares. ** coincidirá recursivamente con los archivos y directorios si ha habilitado globstar.

+0

Gracias. Funciona para mi caso. – user1129812

7

Sí, tiene find separa los nombres de archivo con NUL y usa read para delimitar en NUL. Esto repetirá con éxito sobre cualquier nombre de archivo ya que NUL no es un carácter válido para un nombre de archivo.

#!/bin/bash 
while IFS= read -r -d '' file; do 
    echo "$file" 
    # Do something else. 
done < <(find . -type f -name "*.txt" -print0) 

Alternativamente, si el # do something else no es demasiado complejo, puede utilizar la opción find 's -exec y no tener que preocuparse por la delimitación adecuada

+0

Gracias. Pero el método me parece menos familiar. Lo intentaré más tarde. – user1129812

+1

El uso idiomático de 'encontrar' es algo como esto. El problema con 'para el archivo en $ (buscar ...)' es precisamente que se dividirá en espacios en blanco. En su lugar, use 'find ... | mientras lee el archivo'. Las opciones adicionales para 'leer' son necesarias para enfrentar adecuadamente incluso los nombres de archivo con líneas nuevas, pero si todo lo que necesita para hacer frente es espacios, puede ser un poco más frágil. – tripleee

+0

Este método es una buena solución alternativa para mi caso, ya que permite nombres de archivo arbitrarios permitidos. El método ahora está probado y funciona para mi caso también. – user1129812

Cuestiones relacionadas