Вопрос: Исключить подпапки с определенными файлами в рекурсивном rm -rf / folder / *


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

Пока я не смог найти никого.

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


4
2018-06-13 11:47


Источник


насколько мне известно rm не может исключать шаблоны, вам нужно будет написать функцию или скрипт для этого. - Cobra_Fast


Ответы:


Вы могли бы просто использовать find как это

find some_folder ! -name dontshoot.txt -delete

Это приведет к удалению всех файлов и папок рекурсивно, кроме dontshoot.txt файлы. Как отмечено в других комментариях, всегда полезно протестировать его без удаления, что можно просто сделать так.

find some_folder ! -name dontshoot.txt 

Однако в этом списке будут перечислены все папки, даже те, которые содержат dontshoot.txt но они не будут удалены, поскольку они не будут опущены при использовании -delete,

Редактировать:

Я согласен с тем, что интерпретация вопроса с помощью fedorqui более разумна, чем моя. Удаление только папок, которые не содержат 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 где-то внутри них.


7
2018-06-13 12:00



У меня есть одно сомнение: что, если у нас есть папка t / с dontshoot.txt а также otherfile.txt? Я думаю, что ваш код удалит otherfile.txt, хотя я думаю, что он не должен основываться на OP. - fedorqui
Да, вы правы, я продлил ответ на вашу более разумную интерпретацию вопроса. - buergi
Поздравляю, это такой отличный ответ! - fedorqui


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

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

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

Важный:

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


3
2018-06-13 11:52



В то же время я получил поддержку и сокращение! - fedorqui
Это не я, клянусь! ; D Спасибо за ответ, я проверю его. - mr.nothing
@ mr.nothing, всегда попробуйте свою команду с помощью ls перед использованием rm! - fedorqui
@fedorqui Наверное, лучшее решение. Я пытался что-то сделать с find, но я не думаю, что это условие может быть с этим связано. - glglgl
Проблема с этим решением заключается в том, что он не будет работать рекурсивно. Однако вопрос не дает понять, если это требуется или нет. - buergi


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

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

Назовите

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

Возможно, это может по крайней мере служить идеей на одном из способов подойти к этой проблеме ...


1
2018-06-13 11:58



findэто правильный путь, но этот способ сложный, гораздо проще сразу же исключить файлы в поиске и использовать find -delete флаг. Посмотрите мой андер для полного примера. - buergi