Najlepiej uruchomić polecenie dla każdego pliku w drzewie katalogów

13

Istnieje wiele sposobów, aby to zrobić, w tym pętle w skrypcie powłoki, find i xargs. Który z nich jest najlepszy, a który najbardziej przenośny?

Brian Lyttle
źródło

Odpowiedzi:

13
find . -exec <command> {} \;

dla bieżącego katalogu jako katalogu głównego drzewa lub ogólnie:

find <directory> -exec <command> {} \;
txwikinger
źródło
4
w niektórych systemach find nie ma opcji -exec, można użyć find. | xargs <polecenie>
Hemant,
4
Rzeczywiście, a jeśli musisz coś filtrować, spróbuj -name "*.c"lub na przykład -type dkatalogów ...
Znajdź może robić zaskakująco skomplikowane rzeczy - możesz sprawdzić stronę podręcznika - unixhelp.ed.ac.uk/CGI/man-cgi?find - po pełną listę opcji.
Lucas Jones,
Możesz także uważać na nazwy plików ze spacjami, które mogą złamać podejście -exec i xargs. Zobacz tinyurl.com/ygvgmw5
Shawn Chin
Jeśli to możliwe, użyj find ... | xargs ...idiomu, przetwarza pliki w partiach, a zwykle będzie to szybsze (mniej uruchomionych procesów).
vonbrand
5

Użyj -print0opcji znajdowania i -0opcji, xargsjeśli masz nazwy plików lub katalogów ze spacjami:

find {dir} -print0 | xargs -0r {command}

-print0Opcja znaleźć wypisuje nazw jako NUL-separated zamiast spacji listy rozdzielone, natomiast -0opcja xargsnakazuje mu złamać swoje wejście na NULzamiast spacji. Ponieważ NULjest to jeden z znaków, który jest niedozwolony w nazwach plików w systemie Unix, nie można go pomylić z częścią nazwy pliku.

Dostępna -rjest opcja, xargsktóra nie spowoduje błędu, jeśli nie zostanie wprowadzona.

dhd
źródło
3

Jeśli przenośność jest problemem, trzymałbym się z dala od specyficznych dla powłoki sposobów robienia tego (wiele osób używa wielu różnych powłok, ale ogólnie find i xargs to naprawdę podstawowe narzędzia, których nikt nie odważyłby się zmienić w radykalny sposób) .

Użycie podstawowych argumentów find i xargs powinno dać bardziej przenośne rozwiązanie.

nc3b
źródło
2

Jeśli grupowanie argumentów razem jest dopuszczalne, znajdź | xargs prawdopodobnie zapewni lepszą wydajność, ponieważ wykona polecenie znacznie mniej razy niż find -exec. Jeśli chcesz wykonać polecenie za każdym razem dla każdego pliku lub wykonać w podkatalogu pliku, prawdopodobnie powinieneś użyć find -exec lub -execdir.

Z reguły lepiej unikać pętli specyficznych dla powłoki; find i xargs są wystarczające dla większości scenariuszy.

Eugen Anghel
źródło
1

Upewnij się, że wersja polecenia, którego używasz, nie ma jeszcze flagi operacji rekurencyjnej. :)


źródło
0
find [args] -print | xargs {command}

Działa najlepiej dla mnie.

Josh K.
źródło
2
-1 nie działa dla nazw plików zawierających spacje. Lepiej użyj find -print0 | xargs -0.
starblue