2012-02-04 14 views
6

używam następujący skrypt powłoki bash notować pliki „.txt” rekursywnie w bieżącym katalogu:Bash Shell lista plików za pomocą pętli „for”

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

Jednak niektóre pliki „.txt” w bieżącym katalogu znajdują się spacje w swoich nazwach, np "mój test.txt". Lista zostanie uszkodzona, np. „Mój testing.txt” znajduje się na liście

my 
testing.txt 

Wydaje się, że „za” pętla używa „spacji” (spacja \ n etc) w celu oddzielenia listę plików, ale w moim przypadku chcę używać tylko "\ n", aby oddzielić listę plików.

Czy istnieje sposób, w jaki mogę zmodyfikować ten skrypt, aby osiągnąć ten cel. Dowolny pomysł.

Z góry dziękuję.

+0

W bashie, myślę, że używasz 'find ... -print0' i' IFS = "\ 0" "lub w tym miejscu. Z pewnością istnieją inne pytania na ten temat. –

Odpowiedz

7

Jeśli używasz bash 4, wystarczy użyć glob:

#!/bin/bash                  

shopt -s globstar 

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

Pamiętaj, aby zacytować "$file" lub będziesz mieć ten sam problem w innym miejscu. ** rekursywnie dopasuje pliki i katalogi, jeśli włączysz globstar.

+0

Dzięki. Działa w moim przypadku. – user1129812

7

Tak, należy find oddzielić nazwy plików od NUL i użyć read do ograniczenia na NUL. Pomoże to w powieleniu dowolnej nazwy pliku, ponieważ NUL nie jest poprawnym znakiem dla nazwy pliku.

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

Alternatywnie, jeżeli # do something else nie jest zbyt skomplikowane, można użyć -exec opcję find „s i nie trzeba się martwić o właściwą ograniczającej

+0

Dzięki. Ale metoda wydaje mi się mniej znajoma. Spróbuję później. – user1129812

+1

Idiomatyczne użycie 'find' jest czymś podobnym. Problem z 'dla pliku w $ (find ...)' jest dokładnie taki, że będzie on dzielony na białe znaki. Zamiast tego użyj 'find ... | podczas odczytu pliku ". Dodatkowe opcje "odczytu" są wymagane, aby poprawnie obsłużyć nawet nazwy plików za pomocą znaków nowej linii, ale jeśli wszystko, co musisz zrobić, to spacje, możesz być nieco bardziej leniwa. – tripleee

+0

Ta metoda jest dobrym alternatywnym rozwiązaniem dla mojej sprawy, ponieważ pozwala na dowolne dopuszczalne nazwy plików. Metoda jest teraz testowana poprawnie i działa również dla mojego przypadku. – user1129812