Нужно найти все файлы (рекурсивно), которые имеют подчеркивание в имени файла, а затем удалить их через командную строку.
4 ответа
Это самый безопасный и быстрый вариант:
find /path -type f -name '*_*' -delete
Он не требует конвейерной обработки и не разрывается, если файлы содержат пробелы или символы-заглушки или что-то еще, что могут помешать другие конструкции. Самое простое правило, которое нужно помнить, это никогда не анализировать результаты find
. И никогда не grep
имена файлов, если вы хотите что-то с ними сделать позже. Вы можете сделать практически все что угодно с помощью функции find
.
См. Также: GNU find
Manual - Удаление файлов.
Это включает в себя каталоги, которые считаются файлами. Некоторые другие примеры, использующие xargs , потерпят неудачу, если имя файла содержит пробелы.
find . -name '*_*' -exec rm -rf {} \;
Если вы хотите только обычные файлы:
find . -type f -name '*_*' -exec rm -f {} \;
Хорошо, давайте делать это постепенно.
В качестве первого прохода это просто простое упражнение: передать подстановочный знак в команду 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
find . -type f -regex ".*_.*" | xargs rm -f
объяснение
-type f
находит только файлы
-regex ".*_.*"
выбирает только файлы с подчеркиванием
xargs rm -f
затем принудительно удаляет выбранный файл (никогда не запрашивает перед удалением)