Удалите файлы и каталоги, даже если они не пусты, кроме некоторых каталогов

Я пытаюсь удалить все содержимое каталога с некоторыми исключениями. В настоящее время я использую это:

find . -type f | grep -vZf ../../exclude.file | xargs rm -rf 

exclude.file содержит:

 *log* world* crash-reports banned-ips* 

Я не хочу удалять папки с world , log или сбоями или любым их содержимым (* для покрытия резервных копий, которые генерируются как world.zip ).

Вышеприведенная команда делает это, но не удаляет непустые каталоги. Например, каталог Config оставлен, но мне нужно его удалить.

Я также экспериментировал следующим образом:

 find -maxdepth 0 -not -name '*log*' -not -name 'crash-reports' -not -name 'world*' | xargs rm -rf 

Но я все равно получаю тот же результат.

Есть ли способ сделать это?

-type f будет искать файлы, а не каталоги. -maxdepth 0 будет только найти каталог, который вы ищете ( . ). Вам нужно будет найти файлы, которые вы действительно хотите передать в rm .

Стандартный способ сделать это – исключить каталоги и все их содержимое, как это (непроверенный!):

 find . -mindepth 1 \( -name '*log*' -o -name 'crash-reports' -o -name 'world*' \) -prune -o -print 

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

первый шаг

В первом запуске удалите все файлы (а точнее: не-каталоги):

 find . \( -type d \ \( -name '*log*' -o -name 'world*' -o -name 'crash-reports' -o -name 'banned-ips*' \) \ -prune \) -o \( -type d -o -print \) 

второй шаг

Создайте фиктивный файл в каждом (вспомогательном) каталоге, который нужно пропустить:

 find . -type d \( \ \( -name '*log*' -o -name 'world*' -o -name 'crash-reports' -o -name 'banned-ips*' \) \ -o \( -path '*/*log*/*' -o -path '*/world*/*' -o -path '*/crash-reports/*' -o -path '*/banned-ips*/*' \) \) \ -exec touch {}/dontdeletethisdirecory 

третий шаг

Теперь все пустые каталоги могут быть удалены. Простой подход – передать все каталоги в rmdir . Удаляются только пустые:

 find . -depth -type d -exec rmdir {} \; 

необязательный последний шаг

Теперь вы можете удалить фиктивные файлы:

 find . -type -f -name dontdeletethisdirecory -delete