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