Find -exec cmd {} + vs | xargs

Какой из них более эффективен для очень большого набора файлов и должен использоваться?

find . -exec cmd {} +

или

find . | xargs cmd

(Предположим, что в именах файлов нет смешных символов)

Ответ 1

Разница в скорости будет незначительной.

Но вы должны убедиться, что:

  • Ваш script не предполагает, что нет файл будет содержать пробел, вкладку и т.д. в имя файла; первая версия безопасный, второй - нет.

  • Ваш script не будет обрабатывать файл, начинающийся с "-" в качестве опции.

Итак, ваш код должен выглядеть так:

find . -exec cmd -option1 -option2 -- {} +

или

find . -print0 | xargs -0 cmd -option1 -option2 --

Первая версия короче и легче писать, так как вы можете игнорировать 1, но вторая версия более переносима и безопасна, так как "-exec cmd {} +" является относительно новым вариантом в GNU findutils (с 2005 года многие запущенные системы еще не будут иметь его), и это было багги в последнее время. Также многие люди не знают этого "-exec cmd {} +", как вы можете видеть из других ответов.

Ответ 2

find . | xargs cmd

более эффективен (он запускает cmd как можно несколько раз, в отличие от exec, который запускает cmd один раз для каждого совпадения). Тем не менее, у вас возникнут проблемы, если имена файлов содержат пробелы или фанки.

Предлагается использовать следующее:

find . -print0 | xargs -0 cmd

это будет работать, даже если имена файлов содержат фанковые символы (-print0 делает find печать совпадений с NUL-концами, -0 делает xargs ожидаем этот формат.)