Те, що ви написали, надсилає список імен файлів (та шляхів) 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, завдяки чому пошук генерує вихід, який використовується \0як термінатор, а не як новий рядок. Оскільки системи POSIX дозволяють використовувати будь-які символи, крім \0імені файлу, це справді найбезпечніший спосіб переконатися в правильності передачі аргументів rmабо в застосуванні програми.
Крім того, є те, -execdirщо буде виконуватися rmз каталогу, в якому файл був знайдений, а не в базовому каталозі, і це -depthспочатку почне глибину.