Rekurencyjne iterowanie plików w katalogu można łatwo wykonać:
find . -type f -exec bar {} \;
Powyższe nie działa jednak w przypadku bardziej skomplikowanych rzeczy, w których należy wykonać wiele rozgałęzień warunkowych, zapętlenie itp. Użyłem tego do powyższych celów:
while read line; do [...]; done < <(find . -type f)
Wydaje się jednak, że nie działa to w przypadku plików zawierających niejasne znaki:
$ touch $'a\nb'
$ find . -type f
./a?b
Czy istnieje alternatywa, która dobrze radzi sobie z tak mało znanymi postaciami?
find ... -exec bash -c 'echo filename is in \$0: "$0"' {} \;
jest lepszym sposobem na zrobienie tego.read line
naIFS= read -r line
. Jedyną postacią, która go wtedy złamie, jest nowa linia.-d $'\0'
lepiej.Odpowiedzi:
Jeszcze jedno zastosowanie dla bezpieczeństwa
find
:(Działa to z każdym POSIX-em
find
, ale część powłoki wymaga bash. Z * BSD i GNU find, możesz użyć-print0
zamiast-exec printf '%s\0' {} +
, będzie to nieco szybsze.)Umożliwia to użycie standardowego wejścia w pętli i działa z dowolną ścieżką.
źródło
do echo "Filename is '$REPLY'"
Wykonanie tego jest tak proste, jak:
Lub...
źródło
Najprostszym (ale bezpiecznym) podejściem jest użycie globowania powłoki:
Aby zmienić powyższe rekordy w podkatalogi (w bash), możesz użyć
globstar
opcji; ustawia takżedotglob
dopasowanie plików, których nazwa zaczyna się od.
:Strzeż się, że do wersji bash 4.2
**/
powtarza się w symboliczne linki do katalogów. Od wersji bash 4.3**/
rekursywne są tylko katalogifind
.Innym popularnym rozwiązaniem jest używanie
find -print0
zxargs -0
:Zauważ, że
h:/g
jest to poprawne, ponieważ nazwa pliku zawiera\r
.źródło
Jest to trochę trudne do zrobienia lektury pętlę przenośnie, ale bash w szczególności można spróbować coś jak ten .
Odpowiednia część:
To instruuje,
find
aby wydrukować wynik rozdzielany znakami NUL (0x00) iread
pobrać linie rozdzielane NUL (-d $'\0'
) bez obsługi odwrotnych ukośników jako znaków ucieczki dla innych znaków (-r
) i nie dzielenia słów na wiersze (IFS=
). Ponieważ 0x00 jest bajtem, który nie może występować w nazwach plików lub ścieżkach w systemie Unix, powinno to obsłużyć wszystkie problemy z dziwnymi nazwami plików.źródło
-d ''
jest równoważne z-d $'\0'
.