Интересно, можно ли указать какое-нибудь элегантное условие (параметр может быть?) в rm -rf /folder/* не удалять его подпапки, которые содержат файлы с именем «dontshoot.txt».
Я не смог найти ничего до сих пор.
Заранее спасибо за помощь!
Вы можете просто использовать find как это
find some_folder ! -name dontshoot.txt -delete
Это позволит рекурсивно удалить все файлы и папки, кроме файлов dontshoot.txt .
Как отмечалось в других комментариях, всегда полезно протестировать его без удаления, что можно просто сделать следующим образом.
find some_folder ! -name dontshoot.txt
Однако при этом будут перечислены все папки, даже те, которые содержат dontshoot.txt но они не будут удалены, так как они не будут очищены при использовании -delete .
Редактировать:
Я согласен, что Федорки интерпретирует этот вопрос более разумно, чем мой. Удалять только те папки, которые не содержат dontshoot.txt где-то глубоко внутри их древовидной структуры, было бы ужасное неэффективное решение.
find some_folder -type d -exec \
sh -c "find {} -name dontshoot.txt | grep -q '' || echo rm -fr {}" \;
Объяснение:
Внешняя команда find рекурсивно проходит через some_folder находя все каталоги (-type d) и выполняя (-exec) заданную команду оболочки, заменяя {} относительным путем к найденному каталогу.
Команда find внутри оболочки ищет в найденных каталогах dontshoot.txt . Если ничего не найдено, вывод grep -q '' не будет передан, что, следовательно, вернет False и будет выполнена последняя часть, которая рекурсивно удалит полный каталог (который, конечно, не содержит dontshoot.txt).
Короче говоря, он пересекает все каталоги и удаляет те, которые не содержат dontshoot.txt где-то внутри них.
Невозможно исключить их в команде rm .
Вы можете сделать что-то вроде этого:
for dir in /folder/*
do
echo $dir
if [ ! -f "$dir/dontshoot.txt" ]; then
rm -rf "$dir"
fi
done
Проверьте это с помощью ls вместо rm перед выполнением.
Следующая функция может сработать, но у меня не было времени ее протестировать.
// $1 = directory to remove
// $2 = exclude pattern
function rmx()
{
rm -f $(find $1 * | grep -v $2)
}
Звоните как
rmx get/rid/of/this/ ".*?not-these-files.*?"
Может быть, это может, по крайней мере, послужить идеей для решения этой проблемы ...