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

Hmmph. Я только что разработал однострочную строку для списка всех дубликатов, для вопроса, который оказался дубликатом этого. Как мета. Ну, жаль тратить его впустую, так что я опубликую его, хотя rdfind звучит как лучшее решение.

Это, по крайней мере, имеет то преимущество, что это "настоящий" Unix способ сделать это ;)

find -name '*.mp3' -print0 | xargs -0 md5sum | sort | uniq -Dw 32

Разбираем конвейер:

find -name '*.mp3' -print0 находит все mp3 файлы в поддереве, начинающемся с текущего каталога, и печатает имена с разделителем NUL.

xargs -0 md5sum читает список, разделенный NUL, и вычисляет контрольную сумму для каждого файла.

Вы знаете, что делает sort.

uniq -Dw 32 сравнивает первые 32 символа отсортированных строк и печатает только те, которые имеют одинаковый хэш.

В итоге вы получаете список всех дубликатов. Затем вы можете сократить его вручную до тех, которые вы хотите удалить, удалить хэши и передать список в rm.

2
07.09.2018, 20:59
2 ответа

Попробуйте:

cd /opt &&
  find. \( \
    -path./etc/config -o \
    -path./etc/nginx -o \
    -path./home -o \
    -path./usr/sbin -o \
    -path./var/mlocate \) -prune -o \( \
      -type d -print0 -o -exec rm -f {} + \) |
    tr '\0\n' '\n\0' |
    tac |
    tr '\0\n' '\n\0' |
    xargs -r0 rmdir

-pruneгарантирует, что мы даже не войдем в эти пропущенные каталоги.

Мы удаляем файлы не из каталога -в других каталогах. И оставьте каталоги для обработки после того, как(tacничего не выведет, пока findне завершится, потому что он начинается с последней строки ).

Нам нужно передать список каталогов в обратном порядке rmdir, так как нам нужно удалить содержимое перед самим каталогом. Обратите внимание, что rmdirне удалит не -пустые каталоги.

Обычно используется -depthдля обработки листьев перед ветвями, которые их содержат, но мы не можем использовать -depthс -prune. По той же причине мы не можем использовать -deleteтак, как это подразумевает -depth.

1
27.01.2020, 22:17

1.

Согласно ответу jlliagre на find -exec rm vs -delete\;лучше заменить на +для оптимизации предложения exec, не запуская команду rmдля каждого и каждое совпадение, присутствующее в файловой системе.

2.

Требуется дополнительный ! -path "./", чтобы не генерировать rm: can't remove '.' or '..'.

1
27.01.2020, 22:17

Теги

Похожие вопросы