2012-02-04 10 views
6

Io uso il seguente script Bash Shell per elencare i file ".txt" ricorsivamente sotto la directory corrente:file di elenco Bash Shell utilizzando ciclo "for"

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

Tuttavia, alcuni dei file ".txt" sotto la directory corrente hanno spazi nel loro nome, ad es "il mio testing.txt". L'elenco diventa danneggiato, ad es. "Il mio testing.txt" è elencato come

my 
testing.txt 

Sembra che il ciclo "for" usa "spazio bianco" (spazio, \ n ecc) per separare l'elenco dei file, ma nel mio caso voglio usare solo "\ n" per separare l'elenco dei file.

C'è un modo per modificare questo script per raggiungere questo scopo. Qualche idea.

Grazie in anticipo.

+0

In bash, penso che tu usi 'find ... -print0' e' IFS = "\ 0" 'o circa. Ci sono sicuramente altre domande su questo argomento. –

risposta

7

Se stai usando bash 4, basta usare un glob:

#!/bin/bash                  

shopt -s globstar 

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

Assicurati di citare "$file" o avrete lo stesso problema altrove. ** corrisponderà in modo ricorsivo a file e directory se è stato abilitato globstar.

+0

Grazie. Funziona per il mio caso. – user1129812

7

Sì, avere find separare i nomi file con NUL e utilizzare read per delimitare su NUL. Ciò conterrà con successo su qualsiasi nome di file poiché NUL non è un carattere valido per un nome di file.

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

In alternativa, se il # do something else non è troppo complesso, è possibile utilizzare l'opzione find s' -exec e non devono preoccuparsi di una corretta delimita

+0

Grazie. Ma il metodo mi sembra meno familiare. Ci proverò più tardi. – user1129812

+1

L'uso idiomatico di 'find' è qualcosa del genere. Il problema con 'for file in $ (find ...)' è precisamente che verrà diviso in spazi vuoti. Invece, usa 'trova ... | mentre leggi il file'. Le opzioni aggiuntive di 'read' sono necessarie per gestire correttamente anche i nomi di file con newline, ma se tutto ciò di cui hai bisogno sono spazi, puoi essere un po 'più debole. – tripleee

+0

Questo metodo è una buona soluzione alternativa per il mio caso in quanto consente nomi di file consentiti arbitrari. Il metodo è ora testato OK e funziona anche per il mio caso. – user1129812