Интересно, можно ли указать какое-нибудь элегантное условие (параметр может быть?) в 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.*?"
Может быть, это может, по крайней мере, послужить идеей для решения этой проблемы ...