-delete
подразумевает, -depth
что не работает с -prune
( -depth
начинается с листьев). В руководстве к версии GNU есть предупреждение ( -delete
это расширение FreeBSD, теперь также поддерживаемое GNU find
и некоторыми другими реализациями).
info find --index-search=-delete
Использование действия «-delete» в командной строке автоматически включает параметр «-depth» (* обратите внимание, найти выражения: :). Это может удивить, если вы ранее просто тестировали с помощью «-print», поэтому лучше не забывать явно использовать «-depth».
info find --index-search=-prune
Поскольку «-delete» подразумевает «-depth», использование «-prune» в сочетании с «-delete» может привести к удалению большего количества файлов, чем вы предполагали.
Здесь у вас есть возможность использовать rm
вместо:
find . -name save -prune -o -type f -exec rm -f {} +
(потенциально небезопасно, если там есть каталог, доступный для записи другими, так как можно заставить файлы удалять вне текущего дерева каталогов, заменяя каталоги символическими ссылками во время выполнения этой команды).
Более безопасная альтернатива:
find . -name save -prune -o -type f -execdir rm -f -- {} \;
Это не имеет проблемы, упомянутой выше, но означает запуск по одному rm
на файл. --
Необходимо для реализации FreeBSD, а не GNU один , что имена файлов префиксы с ./
.
В качестве альтернативы, как предложил Костас:
LC_ALL=C find . ! -name save ! -path '*/save/*' -type f -delete
(но это все равно без необходимости спускается в save
каталоги)
Это LC_ALL=C
означает, что *
соответствует любой последовательности байтов (даже тех, которые не образуют допустимых символов в текущей локали). Обратите внимание, что это повлияет на язык сообщений об ошибках (английский вместо языка пользователя).
mv save/ ../some/safer/location
до такой «универсальной» команды удаления (... но, конечно, до вашего поста я бы сделал такую же проверку и столкнулся с той же проблемой!). Теперь найдите хорошего «восстановителя» для файловой системы, в которой были файлы ^^