4

Интересно, можно ли указать какое-нибудь элегантное условие (параметр может быть?) в rm -rf /folder/* не удалять его подпапки, которые содержат файлы с именем «dontshoot.txt».

Я не смог найти ничего до сих пор.

Заранее спасибо за помощь!

3 ответа3

7

Вы можете просто использовать 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 где-то внутри них.

3

Невозможно исключить их в команде rm .

Вы можете сделать что-то вроде этого:

for dir in /folder/*
do
  echo $dir
  if [ ! -f "$dir/dontshoot.txt" ]; then
    rm -rf "$dir"
   fi
done

Важный:

Проверьте это с помощью ls вместо rm перед выполнением.

1

Следующая функция может сработать, но у меня не было времени ее протестировать.

// $1 = directory to remove
// $2 = exclude pattern
function rmx()
{
    rm -f $(find $1 * | grep -v $2)
}

Звоните как

rmx get/rid/of/this/ ".*?not-these-files.*?"

Может быть, это может, по крайней мере, послужить идеей для решения этой проблемы ...

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .