То, что вы написали, отправляет список имен файлов (и путей) rm
, разделенных символом новой строки , но rm не знает, что делать с этим вводом. Ожидаются только параметры командной строки.
xargs
принимает входные данные, обычно разделенные символами новой строки, и помещает их в командную строку, поэтому добавление xargs делает то, что у вас было:
find . -name .svn | xargs rm -fr
xargs
достаточно умен, чтобы передать столько аргументов, rm
сколько может принять. Таким образом, если у вас есть миллион файлов, он может выполняться rm
1 000 000/65 000 раз (если ваша оболочка может принять 65 002 аргумента в командной строке {65k файлов + 1 для rm + 1 для -fr}).
Как умело указали люди, также работают следующие:
find . -name .svn -exec rm -rf {} \;
find . -depth -name .svn -exec rm -fr {} \;
find . -type d -name .svn -print0|xargs -0 rm -rf
Первые две -exec
формы вызывают rm
каждую удаляемую папку, поэтому, если у вас есть 1 000 000 папок, rm
они будут вызваны 1 000 000 раз. Это конечно не идеально. Более новые реализации rm
позволяют вам завершить команду +
указанием, rm
которое примет как можно больше аргументов:
find . -name .svn -exec rm -rf {} +
Последняя версия find / xargs использует print0, что заставляет find генерировать вывод, который используется \0
как терминатор, а не как новая строка . Поскольку системы POSIX допускают любой символ, кроме \0
имени файла, это действительно самый безопасный способ убедиться, что аргументы правильно переданы rm
или приложение выполняется.
Кроме того, есть элемент, -execdir
который будет выполняться rm
из каталога, в котором был найден файл, а не из базового каталога, и элемент, -depth
который будет начинаться с глубины.