То, что вы написали, отправляет список имен файлов (и путей) rm, разделенных символом новой строки , но rm не знает, что делать с этим вводом. Ожидаются только параметры командной строки.
xargs принимает входные данные, обычно разделенные символами новой строки, и помещает их в командную строку, поэтому добавление xargs делает то, что у вас было:
find . -name .svn | xargs rm -fr
xargsдостаточно умен, чтобы передать столько аргументов, rmсколько может принять. Таким образом, если у вас есть миллион файлов, он может выполняться rm1 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который будет начинаться с глубины.