Як мені рекурсивно видаляти каталоги з підстановкою?


51

Я працюю через SSH над WD My Book World Edition. В основному я хотів би почати з певного рівня каталогу та рекурсивно видаляти всі відповідні підкаталоги .Apple*. Як би я пішов про це?

я намагався

rm -rf .Apple* і rm -fR .Apple*

ні видалені каталоги, що відповідають цьому імені в підкаталогах.

Відповіді:


73

find дуже корисно для вибіркового виконання дій на цілому дереві.

find . -type f -name ".Apple*" -delete

Тут -type fпереконайтеся, що це файл, а не каталог, а може бути і не саме те, що вам потрібно, оскільки воно також буде пропускати символьні посилання, сокети та інші речі. Ви можете використовувати ! -type d, що буквально означає не каталоги, але тоді ви також можете видалити символи та заблокувати пристрої. Я б запропонував переглянути -typeприсудок на сторінці man для find.

Щоб це робити суворо за допомогою шаблону, вам потрібна розширена підтримка оболонки. Bash v4 має globstarопцію , яка дозволяє рекурсивно співставляти підкаталоги за допомогою **. zshа kshтакож підтримують цю модель. Використовуючи це, ви можете зробити rm -rf **/.Apple*. Це не стандарт POSIX і не дуже портативний, тому я б уникав використовувати його в сценарії, але для одноразової інтерактивної дії оболонки це добре.


3
Я можу приступити find . -type d -name .Apple*до роботи - у ньому перераховані всі папки. Однак він не вдається, коли я додаю -deleteв кінці. Він просто повертається з підсумком використання. Він працює на BusyBox v1.1.1. Це має значення?
codedog

1
-deleteтакож не POSIX. **була введена zshна початку 90-х. Зараз це (за хронологічним порядком появи) також у ksh93, fish, bash та tcsh.
Stéphane Chazelas

1
+1 заrm -rf **/.Apple*
Андрій Бойко

1
@codedog, якщо -deleteвін не працює, -exec rm -f {} +замість цього.
Wildcard

1
Чи можете ви findбути багатослівними, як це видаляє? Я припускаю, що метод "globstar" зробив би це, додавши -vперемикач.
Деміс

16

Я зіткнувся з проблемами використання findз- -deleteза навмисної поведінки find(тобто відмовився видаляти, якщо шлях починається з ./, що вони роблять у моєму випадку), як зазначено на його довільній сторінці:

 -delete

Видаліть знайдені файли та / або каталоги. Завжди повертає правду. Це виконується з поточного робочого каталогу, оскільки пошук повторюється вниз по дереву. Він не намагатиметься видалити ім'я файлу з символом "/" у своєму імені шляху відносно ". з міркувань безпеки.
Ця опція передбачає глибинну першу обробку.
Наступні посилання не сумісні з цією опцією.

Натомість мені вдалося просто зробити

find . -type d -name 'received_*_output' -exec rm -r {} +

У вашому випадку, здається, що цитування глобуса (зірочка, *) було рішенням, але я хотів надати свою відповідь у випадку, якщо хтось інший мав подібну проблему.

ПРИМІТКА: Раніше моя відповідь полягала в наступному, але @Wildcard вказував на недоліки безпеки в цьому.

find . -type d -name 'received_*_output' | xargs rm -r

1
Тут немає вагомих причин для використання xargs. -exec rm -r {} \;або, що ще краще, -exec rm -r {} +буде добре, не виходячи з назви спеціальних символів. Див. Чому зациклість на поганій практиці пошуку результатів пошуку?
Wildcard

Це добре знати. Не варто знижувати голоси, IMO, оскільки команда все-таки виконує завдання, але оптимізація продуктивності цінується.
Пат

1
Якби це була лише оптимізація продуктивності, я б погодився з вами, але це не так. Це отвір для безпеки. Ви неправильно обробляєте файли з пробілами у своїх іменах, а шкідливо створене ім’я файлу призведе до втрати даних. Також дивіться наслідки для безпеки забування процитувати змінну в оболонках bash / POSIX ; Деякі з них застосовні, і це, принаймні, може дати вам деяке уявлення про тип проблем, про які я говорю.
Wildcard

Спробуйте mkdir -p $'blah\nDocuments\n/etc\n/home\n/received__output'у своєму каталозі, а потім знову запустіть ту саму команду, якщо ви не вірите, що існує можливість втрати даних. Або, так як мова йде про Mac OS, mkdir -p $'blah\nDocuments\n/Users\n/Applications\n/received__output'. ( Попередження: якщо ви це зробите, ви видалите всі свої файли. Ось такий мій погляд.)
Wildcard

0

Можливо, це те, що у вашій команді rm / find немає нічого поганого, але що у користувача, з яким ви ввійшли, насправді немає дозволів на видалення. Використовуйте ls -lдля переліку речей з їх дозволами, і ви можете визначити, з ким ви знаходитесь, idі groupsкоманди (або вони повинні бути доступними). Якщо ви "неправильний користувач" для цього, вам потрібно буде або змінити дозволи / права власності на файли, або перейти на іншого користувача.



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.