Как рекурсивно удалить каталоги с подстановочными знаками?


52

Я работаю через 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предикат на странице руководства find.

Чтобы сделать это строго с подстановочным знаком, вам нужна расширенная поддержка оболочки. Bash v4 имеет globstarопцию , которая позволяет вам рекурсивно сопоставлять подкаталоги, используя **. zshа kshтакже поддерживать эту модель. Используя это, вы можете сделать rm -rf **/.Apple*. Это не стандарт POSIX и не очень переносимый, поэтому я бы не использовал его в скрипте, но для одноразового действия интерактивной оболочки это нормально.


3
Я могу приступить find . -type d -name .Apple*к работе - в нем перечислены все папки. Тем не менее, это не удается, когда я добавляю -deleteв конце. Это просто возвращается с кратким описанием использования. Он работает на BusyBox v1.1.1. Это имеет значение?
— кодирование

1
-deleteтоже не POSIX. **был введен zshв начале 90-х годов. Это теперь (в хронологическом порядке появления) также в ksh93, fish, bash и tcsh.
— Стефан Шазелас

1
+1 дляrm -rf **/.Apple*
— Андрей Бойко

1
@codedog, если -deleteне работает, используйте -exec rm -f {} +вместо этого.
— Wildcard

1
Можете ли вы findбыть многословным, когда он удаляет? Я полагаю, что метод "globstar" сделает это, добавив -vпереключатель.
— Демис

17

Я столкнулся с проблемами при использовании 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 {} +будет делать то же самое без ошибок в именах специальных символов. См. Почему циклическая обработка вывода find является плохой практикой?
— 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.