2009-08-21 16 views
15

zacząłem z tym:Jak zrobić coś dla każdego pliku w katalogu używając bash?

command * 

Ale to nie działa, gdy katalog jest pusty; * wieloznacznik staje się dosłownym "*" znakiem. Więc zmieniłem to na:

for i in *; do 
    ... 
done 

który działa, ale znowu nie, jeśli katalog jest pusty. Użyłem ls:

for i in `ls -A` 

, ale oczywiście, nazwy plików z spacji w nich się podzielić. Próbowałem sklejaniu na przełączniku -Q:

for i in `ls -AQ` 

który powoduje, że nazwy jeszcze zostać podzielona, ​​tylko o charakterze cytatem na początku i na końcu nazwy. Czy brakuje tu czegoś oczywistego, czy jest to trudniejsze, niż powinno?

+0

Głupie nazwy plików systemu Windows ze spacjami! Zamierzam zostać wbity za to, ale ...moja rada dla współpracowników dotycząca skryptów: jak tylko twój skrypt ma "jeśli" lub "kiedy", czas odłożyć "powłokę" i odebrać "perl" :-(Jestem pewien, że jest jakiś masochistyczny sposób na zrobienie tego Nawiasem mówiąc, rozwiązanie Bombe find -exec musi ograniczać głębokość, więc podkatalogi również nie są pobierane – Roboprog

Odpowiedz

35

Zakładając, że tylko chce coś zrobić do plików, proste rozwiązanie jest do badania, jeśli $ i jest to plik:

for i in * 
do 
    if test -f "$i" 
    then 
     echo "Doing somthing to $i" 
    fi 
done 

Należy naprawdę zawsze takie testy, bo prawie na pewno nie chcą traktować pliki i katalogi w ten sam sposób. Zwróć uwagę na cytaty z "$ i", które zapobiegają problemom z nazwami plików zawierającymi spacje.

+1

Wydaje się to być najprostszą odpowiedzią.To dziwne, że tak wiele przewodników po skryptach powłoki zawsze Ci mówi używać *, ale nie zawsze wspominaj o dosłownym zachowaniu "*", gdy nie ma plików w CWD –

11

find może być tym, co chcesz.

find . | while read file; do 
    # do something with $file 
done 

A może tak:

find . -exec <command> {} \; 

Jeśli nie chcesz, aby wyszukać zawierać podkatalogów może trzeba dodać połączenie -type f i -maxdepth 1 do polecenia find. Szczegółowe informacje można znaleźć na stronie find man page.

+4

Dodatkowa zaleta nie łamania się, gdy masz 10.000+ plików w katalogu – MSalters

+0

@MSalters Kto ma tak wiele? Ostatnim razem miałem tak dużo, gdy zapomniałem, że program podzielony spodziewał się bajtów, a nie liczby podzielonych plików ... –

+2

Dzieje się cały czas i częściej niż myślisz – Bombe

2

to powinno załatwić sprawę:

find -type d -print0 | xargs -n 1 -0 echo "your folder: {} !" 
find -type f -print0 | xargs -n 1 -0 echo "your file: {} !" 

print0/0 są tam, aby uniknąć problemów z białymi znakami

+1

jesteś naprawdę lepszy korzystając z find -type d -exec Echo "Twój folder: {}" \; ... xargs napotyka problemy, jeśli twoja ścieżka jest zbyt głęboka. –

8

To zależy od tego, czy masz zamiar wpisać to w wierszu polecenia, a które polecenie aplikujesz do plików.

Jeśli zostanie wpisany, możesz wybrać drugi wybór i zastąpić coś nieszkodliwym dla polecenia. Lubię używać echa zamiast mv lub rm, na przykład.

umieścić to wszystko w jednym wierszu:

for i in * ; do command $i; done 

Kiedy to działa - czy można zobaczyć, gdzie to się nie powiedzie, i czy jest to nieszkodliwe, można nacisnąć klawisz strzałka w górę, edytować polecenia i spróbuj ponownie.

5

Zastosowanie shopt aby zapobiec ekspansji * .txt

shopt -s nullglob 
for myfile in *.txt 
do 
    # your code here 
    echo $myfile 

done 
Powiązane problemy