массовое удаление файлов

массовое удаление файлов

Я хотел бы удалить все файлы txt, xls, pdf в каталоге, а также его подкаталоги. Я хотел бы сохранить все остальное.

find . -type f ! -iname '*.xml$,.png$,.jpeg$,.gif$,' -delete

это, казалось, сделало это, но это удалило некоторые другие файлы, которые мне нужны. Как я могу добиться этого, не удаляя ничего другого?

решение1

Вместо этого сделайте следующее:

find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -delete

Вы также можете использовать регулярные выражения:

find . -type f -iregex '.*\.\(xml\|png\|jpeg\|gif\)$' -delete

решение2

По сути, существует 4 способа решения этой проблемы с помощью find.

Метод №1 - использование-delete

$ find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -delete

Как уже упоминалось в этом разделе вопросов и ответов, этот метод является самым быстрым и наименее ресурсоемким. Цитата изнайти онлайн-документы:

10.1.6 Использование действия `-delete'


Наиболее эффективным и безопасным методом решения этой проблемы является использование действия `-delete':

 find /var/tmp/stuff -mtime +90 -delete

Эта альтернатива более эффективна, чем любое из -exec' orдействий -execdir', поскольку она полностью избегает накладных расходов на разветвление нового процесса и использование exec' to run/bin/rm'. Она также обычно более эффективна, чем xargs' for the same reason. The file deletion is performed from the directory containing the entry to be deleted, so theдействие -delete', имеет те же преимущества безопасности, что и действие `-execdir'.

Действие `-delete' было введено семейством операционных систем BSD.

ПРИМЕЧАНИЕ:При таком подходе следует помнить об одном: использование -deleteподразумевает также переключатель -depth. Что это значит? Вот пример того, как -deleteможно обжечься, если не быть осторожным.

Например, скажем, у меня есть рабочий каталог subversion, в котором я хочу очистить некоторые файлы, но оставить его подкаталоги .svn нетронутыми. Я могу использовать следующую команду, чтобы сделать это:

$ find . -not "(" -name .svn -type d -prune ")" -type f -print
./a.txt

Но поскольку -deleteвключает -depthпереключатель, файлы, которые фактически будут обрабатываться:

$ find . -not "(" -name .svn -type d -prune ")" -type f -print -depth
./.svn/all-wcprops
./.svn/entries
./.svn/format
./.svn/text-base/a.txt.svn-base
./a.txt

По этой причине при использовании -deleteнеобходимо соблюдать осторожность.

Метод №2 --exec command {} +

$ find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -exec rm {} \+

По сравнению с -deleteметодом, это, скорее всего, следующий лучший вариант с точки зрения производительности и переносимости между Unix. Нотация -exec ... {} +работает следующим образом:

из страницы поиска руководства

Этот вариант действия -exec запускает указанную команду для выбранных файлов, но командная строка создается путем добавления каждого выбранного имени файла в конец; общее количество вызовов команды будет намного меньше количества соответствующих файлов. Командная строка создается примерно так же, как xargs создает свои командные строки. В команде допускается только один экземпляр `{}'. Команда выполняется в начальном каталоге.

Таким образом, по сути, этот метод работает аналогично xargs, но без необходимости преодолевать препятствия, передавая вывод find через конвейер в xargs.

Метод №3 -xargs

$ find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -print0 | xargs -0 rm -f

Будет find ... -print0создан список файлов, соответствующих указанным критериям. Затем этот список передается по каналу в xargs. -print0Переключатель помещает символ ASCII NUL в качестве разделителя между каждым результатом поиска. -0Переключатель on xargsпредполагает, что передаваемые файлы разделены символами ASCII NUL.

По сравнению со способами № 1 и № 2 этот метод будет иметь производительность, аналогичную способу № 2, однако этот -print0переключатель не поддерживается всеми Unix-системами.

Метод №4 --exec command {} \;

$ find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' | exec rm -f {} \;

По сравнению с первыми тремя методами, этот наименее производительный. Он буквально вызывает команду rmдля каждого отдельного файла, который findкоманда находит.

Дополнительные соображения по поводу безопасности

Одна вещь, которая может быть не столь очевидной при использовании любого из вышеперечисленных методов, заключается в том, что некоторые из методов более безопасны, чем другие. Вы, вероятно, говорите себе: ... безопасность? .. что? Вот пример.

Предположим, что вы являетесь пользователем root и выполняете следующую команду:

$ find /var/tmp/somedir -type f -exec rm {} \;

Без вашего ведома кто-то злонамеренно создал ссылку на /etcкаталог в /var/tmp/somedir. При запуске указанной выше команды /etcкаталог также будет удален. Эта проблема существует при любом из методов удаления файлов, за исключением варианта -delete(метод № 1).

вкратце;

Самый быстрый и безопасный способ удалить файлы с помощью find — использовать -delete. Использование xargs -0может быть схожим по производительности, но не таким безопасным. -deleteДействие не является полностью переносимым. Наиболее эффективной переносимой альтернативой является -exec ... +, но это небезопасно и не поддерживается версиями GNU findutils до 4.2.12.

Рекомендации

решение3

Есть небольшая неточностьответ слм.

ПРИМЕЧАНИЕ и отказ от ответственности: это должен быть комментарий кответ слмно сейчас я пока не могу комментировать.

Пример «кто-то злонамеренно создал ссылку», приведенный вДополнительные соображения по поводу безопасностине совсем точен как в отношении жестких ссылок Unix, так и в отношении мягких ссылок Unix.

Чтобы понять разницу между ними, см.Жесткие ссылки и символические ссылки в Unixили погуглите.

Для мягких ссылок (самый используемый тип) GNU findиBDS find неследовать символическим ссылкам, если не используется специальный -Lфлаг для принудительного следования по символической ссылке. [См. man find]

Так что этот пример, скорее всего, не будет проблемой, если только высила findследовать по мягким ссылкам с использованием -Lфлага. Это опасный выбор, в любом случае.

Для жестких ссылок, findбудет следовать ссылке надругой файлно учтите, что жесткая ссылка надругой каталог«вероятно, потерпит неудачу», как показано в примере man lnдля GNU ln:

   -d, -F, --directory
          allow the superuser to attempt to hard link directories (note: will probably
          fail due to system restrictions, even for the superuser)

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

Обратите внимание, что некоторые реализации BDS вообще lnне имеют такой возможности.-d

Связанный контент