Рекурсивно удалять файлы

140

Есть ли у кого-нибудь решение для удаления этих надоедливых файлов ._ и .DS_Store, которые появляются после перемещения файлов с Mac на Linux Server?

указать начальный каталог и отпустить? например / var / www / html / down ...

JT.
источник
Хотя это не дубликат IMO, вам следует взглянуть на это: stackoverflow.com/questions/1280429/…
Grundlefleck
Хотя не то, о чем вы спрашиваете. Я бы сказал, что это лучшее решение: unix.stackexchange.com/questions/9665/…
Виктор

Ответы:

169

перейдите в каталог и используйте:

find . -name ".DS_Store" -print0 | xargs -0 rm -rf
find . -name "._*" -print0 | xargs -0 rm -rf

Не тестировалось, сначала попробуйте их без xargs!

Вы можете заменить точку после find на каталог вместо того, чтобы сначала переходить в каталог.

find /dir/here ...
X-Istence
источник
2
Я знаю, что его вопрос не касался этого, но я никогда не могу вспомнить: обрабатывает ли ваш пример имена файлов с пробелами?
Grundlefleck 06
4
Да, для этого нужны print0 и -0 для xargs. Обычно он не обрабатывает пробелы правильно, однако с print0 он будет печатать имя файла с нулевым символом в конце строки, который xarg с -0 затем будет использовать для передачи полного пути к xargs без шанса иметь пробел используется второй или третий параметр команды rm, что может быть очень плохо!
X-Istence 06
7
@X: более новый findutils поддерживает -deleteдействие, которое может сократить это. @JT: рекурсивный поиск в .. Зависит от того, сколько там файлов и подкаталогов ... не можете ли вы просто запретить их загрузку?
ephemient 06
1
Использование -r(рекурсивного) флага в этом случае не рекомендуется, поскольку вы не хотите удалять какие-либо каталоги ..
Дэниел Зохар
2
@IlmariKaronen: хорошая мысль. Разве не command rmбыло бы лучшего (то есть более прямого) решения? (Под "прямым" я подразумеваю, что он имеет дело именно с рассматриваемой проблемой и ничем другим, и, следовательно, с меньшей вероятностью будет иметь какие-либо нежелательные побочные эффекты, а также будет более понятным для всех, кто должен поддерживать код позже.)
иконоборчество
93
find /var/www/html \( -name '.DS_Store' -or -name '._*' \) -delete
OneOfOne
источник
88

Более новая версия findutils поддерживает -delete:

find . -name ".DS_Store" -delete

Добавить, -printчтобы также получить список удалений.

Я считаю, что команда будет работать на вас, если у вас есть современная система POSIX. По крайней мере, он работает для меня в OS X 10.8 и работает для других, кто тестировал его в macOS 10.12 (Mojave).

Кредит @ephemient в комментарии к сообщению @ X-Istence (подумал, что это было достаточно полезно, чтобы оправдать собственный ответ).

крысоловка
источник
1
Работает и в OSX 10.6.
hoss
4
Самое чистое и простое решение, +1!
Limist
7
@OneOfOne: как говорится в моем комментарии, я получил это от @ ephemient. Как новичок в bash, я нашел ваше (возможно, более правильное) решение гораздо менее читабельным и удобным. Они могут быть функционально идентичными, но я считаю, что этот синтаксис обеспечивает большую ясность.
rattray 06
1
Символ '.' не требуется, поскольку findпо умолчанию выполняется рекурсивный переход в текущий рабочий каталог.
Том Рассел
В более новых версиях программы каталог может быть опущен, и это будет означать текущий рабочий каталог ( wikipedia ). Вам все еще нужна .macOS 10.12 (Sierra).
Дем Пилафян
18

Простая команда:

rm `find ./ -name '.DS_Store'` -rf
rm `find ./ -name '._'` -rf

Удачи!

KimKha
источник
1
Это прекрасно работает. НО осторожно, я просто использовал эту rm -i находку ./ -name '* py'` -rf , which did NOT prompt me to delete files. you will need to take it on the end (i.e. -rfi`). Слава богу за мой сценарий резервного копирования.
ryanjdillon
1
Если файлов слишком много, выдается сообщение об ошибке:-bash: /bin/rm: Argument list too long
Виктор
12
cd /var/www/html && find . -name '.DS_Store' -print0 | xargs -0 rm
cd /var/www/html && find . -name '._*' -print0 | xargs -0 rm
mopoke
источник
2
Этот мне понравился больше просто потому, что в «rm» нет «-r», который не нужен для этой конкретной задачи.
lotoffreetime
6

Вы можете переключиться на zsh вместо bash. Это позволяет использовать ** для сопоставления файлов в любом месте дерева каталогов:

$ rm /var/www/html/**/_* /var/www/html/**/.DS_Store

Вы также можете комбинировать их так:

$ rm /var/www/html/**/(_*|.DS_Store)

У Zsh есть много других функций, которых не хватает bash, но только на эту стоит переключиться. Он доступен в большинстве (возможно, во всех) дистрибутивах Linux, а также в cygwin и OS X.

Вы можете найти дополнительную информацию на сайте zsh .

Дэйв Кирби
источник
1
Возможная проблема: поскольку вы не используете xargs, вы можете столкнуться с ограничением длины аргумента командной строки. Кроме того, Bash 4 **тоже поддерживает :-) (хотя и не по умолчанию, shopt -s globstarнеобходимо установить)
ephemient 06
4
find . -name "FILE-TO-FIND"-exec rm -rf {} \;
Мартин Беккет
источник
Использование exec для каждого найденного файла не является быстрым. Быстрее распечатать их, а затем использовать xargs для однократного вызова rm.
X-Istence 06
3
Однако, если у вас есть findподдерживающий его, +он похож на xargs: find . -name "FILE-TO-FIND" -exec rm -rf {} +- (также вы пропустили пробел раньше -exec)
Приостановлено до дальнейшего уведомления.
3
у нас никогда не было xargs. И нам пришлось идти в школу пешком, в обе стороны в гору .......
Мартин Беккет
3

Пример рекурсивного удаления "Thumbs.db";

find . -iname "Thumbs.db" -print0 | xargs -0 rm -rf

Подтвердить:

find . -iname "Thumbs.db"

Теперь это не должно отображать какие-либо записи с «Thumbs.db» внутри текущего пути.

парасриш
источник
Убедитесь, что в вашем ответе содержится список того, что удаляется, и объясняется, почему кто-то может захотеть использовать xargsи print0вместо exec(есть причины).
Джош Хабдас
3

Лучше увидеть, что удаляется, добавив к этому ответу -print

find /var/www/html \( -name '.DS_Store' -or -name '._*' \) -delete -print
Ахмад Юсофан
источник
2

если у вас Bash 4.0 ++

#!/bin/bash
shopt -s globstar
for file in /var/www/html/**/.DS_Store /var/www/html/**/._ 
do
 echo rm "$file"
done
призрачная собака74
источник
2
Запускать новую копию rm для каждого файла расточительно.
X-Istence 08
2
Преждевременная оптимизация @ X-Istence расточительна
Люцина
Проголосовали за оригинальность и использование последних инноваций bash.
Джош Хабдас
1

Несколько замечаний:

'-delete' не рекурсивен. Поэтому, если .TemporaryItems (папка) содержит файлы, команда не выполняется.

Существует множество этих надоедливых файлов, созданных Mac: .DS_Store ._. DS_Store .TemporaryItems .apdisk

Эта одна команда обращается ко всем из них. Сохраняет от многократного выполнения поиска для нескольких совпадений.

find /home/foo \( -name '.DS_Store' -or -name '._.DS_Store' -or -name '._*' -or -name '.TemporaryItems' -or -name '.apdisk' \) -exec rm -rf {} \;
Каран Бхалла
источник
0

Это тоже работает:

sudo rm -rf 2018-03-*

вот ваши удаляющие файлы с именами формата 2018-03- (что-то еще)

будь проще

пранавхд
источник
Вы не объясняете, когда кто-то может захотеть поставить перед командой префикс, sudoи не предоставляете никакой информации о том, как это rmработает в контексте вашего ответа.
Джош Хабдас