Назад | Перейти на главную страницу

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

У меня глубокая структура каталогов с большим количеством файлов (около 1M). Я хотел бы выполнить команду против каждого. (В моем случае это файлы png, с которыми я хотел бы запустить optipng.)

Я пробовал это:

find . -name *.png | xargs sudo optipng -o2

но я получаю сообщение об ошибке argument list too long.

Я предполагаю, что xargs должен справиться с этим и что должна быть проблема с моим синтаксисом.

Выполняйте exec напрямую с помощью find, а не через xargs.

sudo find . -name '*.png' -exec optipng -o {} +

Использование sudo как команды для выполнения xargs как видите, не работает. Попробуйте по-другому:

find . -name '*.png' | sudo xargs optipng -o2

Разница в том, что ваша версия создает такую ​​команду, как

 sudo optipng -o2 file1 file2 file3 file4 ......

а sudo не может обрабатывать так много параметров.

В противном случае выполняется sudo один раз, который, в свою очередь, запускает xargs который затем генерирует команду вроде

optipng -o2 file1 file2 file3 file4 ......

и если optipng может обрабатывать многие файлы в качестве параметров, он должен работать.

Если это все еще не сработает, вам придется использовать -exec вместо этого, как в ответе Герайнта, но это должно быть вашим последним средством.

Еще один выстрел в это:

find . -name '*.png' | sudo xargs -n x -P y optipng -o2

Что запустит один вариант для x файлы и y такие процессы выполняются параллельно (может помочь вам выполнить работу быстрее, если у вас есть свободные ядра). Имея x значение больше 10, вероятно, не окажет большого влияния на производительность.

Это поможет сделать список аргументов коротким. Так что вы, вероятно, могли бы переехать sudo туда, где она у вас была, но это просто еще одна команда, которую нужно будет запускать для каждой партии.