Лучший способ выполнить команду для каждого файла в дереве каталогов

13

Существует несколько способов сделать это, включая циклы в shell-скрипте, find и xargs. Какой из них лучше, а какой самый портативный?

Брайан Литтл
источник

Ответы:

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

для текущего каталога в качестве корня дерева или вообще:

find <directory> -exec <command> {} \;
txwikinger
источник
4
в некоторых системах find нет опции -exec, где вы можете использовать find. | xargs <Command>
Hemant
4
Действительно, и если вам нужно что-то фильтровать, попробуйте -name "*.c"или, например, -type dдля каталогов ...
Find может делать удивительно сложные вещи - вы можете проверить страницу руководства - unixhelp.ed.ac.uk/CGI/man-cgi?find - для получения полного списка опций.
Лукас Джонс
Вы также можете следить за именами файлов с пробелами, которые могут нарушить подходы -exec и xargs. См. Tinyurl.com/ygvgmw5
Шон Чин
Если возможно, используйте find ... | xargs ...идиому, она обрабатывает файлы в пакетном режиме, и это обычно будет быстрее (меньше запущенных процессов).
vonbrand
5

Используйте -print0опцию для поиска и -0опцию, xargsесли у вас есть имена файлов или каталогов с пробелами:

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

-print0Возможность найти распечатывает имена файлов как NUL-разделенное , а не пробелами список разделенных, в то время как -0опция xargsинструктирует их , чтобы разбить его на вход , NULа не пробелами. Поскольку NULэто один из символов, который не допускается в именах файлов Unix, его нельзя принять за часть имени файла.

-rВариант есть , так что xargsне будет выдавать ошибку , если он не имеет входа.

DHD
источник
3

Если бы переносимость была проблемой, я бы держался подальше от специфических для оболочки способов сделать это (есть много людей, использующих множество различных оболочек, но в целом find и xargs - действительно базовые инструменты, которые никто не осмелится радикально изменить) ,

Использование основных аргументов find и xargs должно дать вам более переносимое решение.

nc3b
источник
2

Если группировка аргументов приемлема, найдите | Вероятно, xargs даст лучшую производительность, так как он будет выполнять команду намного реже, чем find -exec. Если вы хотите выполнять команду каждый раз для каждого файла или выполнять в подкаталоге файла, вам, вероятно, следует использовать find -exec или -execdir.

Как правило, предпочтительнее держаться подальше от специфичных для оболочки циклов; find & xargs достаточно для большинства сценариев.

Евгений Ангел
источник
1

Убедитесь, что версия команды, которую вы используете, еще не имеет флага для рекурсивной операции. :)


источник
0
find [args] -print | xargs {command}

Лучше всего работает для меня.

Джош К
источник
2
-1 Не будет работать для имен файлов, содержащих пробелы. Лучше использовать find -print0 | xargs -0.
звездный