5

Нужно найти все файлы (рекурсивно), которые имеют подчеркивание в имени файла, а затем удалить их через командную строку.

4 ответа4

11

Это самый безопасный и быстрый вариант:

find /path -type f -name '*_*' -delete

Он не требует конвейерной обработки и не разрывается, если файлы содержат пробелы или символы-заглушки или что-то еще, что могут помешать другие конструкции. Самое простое правило, которое нужно помнить, это никогда не анализировать результаты find. И никогда не grep имена файлов, если вы хотите что-то с ними сделать позже. Вы можете сделать практически все что угодно с помощью функции find .

См. Также: GNU find Manual - Удаление файлов.

2

Это включает в себя каталоги, которые считаются файлами. Некоторые другие примеры, использующие xargs , потерпят неудачу, если имя файла содержит пробелы.

find . -name '*_*' -exec rm -rf {} \;

Если вы хотите только обычные файлы:

find . -type f -name '*_*' -exec rm -f {} \;
0

Хорошо, давайте делать это постепенно.

В качестве первого прохода это просто простое упражнение: передать подстановочный знак в команду find , не забывая процитировать его в кавычках и выполнить команду rm для каждого найденного файла:

find ${BASE_DIR}/ -name '*_*' -exec rm {} \;

Но, конечно, это ужасно неэффективно. Он запускает целый процесс rm для каждого отдельного файла. Поэтому, хотя мы могли бы сделать короткий обход \+ , это не то место, где мы собираемся в конечном итоге, поэтому давайте выберем более короткий путь и xargs чтобы объединить имена файлов в группы:

find ${BASE_DIR}/ -name '*_*' -print | xargs rm

Но у этого есть две дыры в безопасности. Во-первых, если любое найденное имя файла начинается со знака минус, rm будет рассматривать его как параметр командной строки, а не как имя файла, и выдаст ошибку. (Версия -exec rm {} также имеет эту проблему.) Во-вторых, имена файлов, содержащие пробелы, не будут правильно обрабатываться xargs . Таким образом, дальнейшая итерация должна сделать это немного более пуленепробиваемым:

find ${BASE_DIR}/ -name '*_*' -print0 | xargs -0 rm --

И, конечно же, есть интерактивные функции rm которые вам, вероятно, не нужны:

find ${BASE_DIR}/ -name '*_*' -print0 | xargs -0 rm -f --

-print0 и -0 не являются стандартными, но GNU find и xargs , а также FreeBSD find и xargs понимают их. Однако даже это немыслимо. Нам не нужно создавать никаких дополнительных процессов вообще. GNU и FreeBSD find s оба могут вызвать unlink(2) системный вызов напрямую:

find ${BASE_DIR}/ -name '*_*' -delete

В качестве последней меры предосторожности, которая помешает вам делать больше, чем вы предполагали в определенных обстоятельствах, помните, что файловая система может содержать не только обычные файлы:

find ${BASE_DIR}/ -name '*_*' -type f -delete
-2

find . -type f -regex ".*_.*" | xargs rm -f

объяснение
-type f находит только файлы
-regex ".*_.*" выбирает только файлы с подчеркиванием
xargs rm -f затем принудительно удаляет выбранный файл (никогда не запрашивает перед удалением)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .