Delete all folder not containing filename matching glob/regex

I want to do the following. I have depth 2 file hierarchy like this:

A
| B
| | g
| | h50000
| C

Where A, B, C are folders. I want to delete all folders without files matching specific patters, (in my case 50000 is pattern, glob style) on depth level 2. (In this example folder C should only be deleted, alongside its content, while A remains)

In my application I'm fine if I delete all folders where neither children contains filename matching a pattern. (It would make it easier to not delete A without specifying on which depth I'm deleting).

How would I be able to do it in bash on Linux machine?

1
задан 1 March 2017 в 20:23
1 ответ

С помощью find вы можете исключить шаблон:

find \! -name '*50000*' -delete

Экранирование ! необходимо из-за его использования в оболочках.

Каталоги с содержимым не будут удалены.

ВНИМАНИЕ: поскольку из вашего вопроса мне это немного неясно - это БУДЕТ удалять другие файлы в папках, которые имеют шаблон 50000 , например A / B / g будут удалены, и будут сохранены только файлы (и каталоги) с именем 50000 (включая их родительские каталоги)!


Для удаления всех каталогов, у которых нет 50000 файл в них и хранить каталоги с такими файлами вместе с другим содержимым этого каталога, я бы предложил двухэтапный метод:

  1. перечислить все файлы и каталоги и сохранить в текстовый файл

      находить .  -depth -mindepth 1> все
     
  2. список каталогов, которые необходимо сохранить (только найти файл и распечатать каталог)

     найти.  -depth -name '* 50000 *' printf '% h \ n'> сохранить
     
  3. выберите удаляемые файлы и каталоги с помощью перевернутого grep

     grep -vf keep all> deletable
     
  4. использовать этот список для удаления (просто образец)

     при чтении строки
    делать
    
      находить .  -wholename "$ line" -delete
    
    сделано <удаляемый
     

Обратите внимание, что точка 4 выполняется медленно из-за того, что она является сценарием оболочки построчно. Не самый лучший, но выполнит свою работу.


Альтернативный вариант (и проще): если у вас есть root-доступ, временно измените атрибут i , предотвращая изменения, включая удаление, удалите все (так как удаление не разрешено для файлов и каталогов с метками i ) и в конце удалить флаг i .

#%h goes for parent directories of our hits
find -name '*5000*' -printf '%h\0' | xargs -0 chattr -R +i '{}'
#be careful now ....
rm -r *
chattr -i -R *
1
ответ дан 3 December 2019 в 23:33

Теги

Похожие вопросы