Назад | Перейти на главную страницу

Удалить всю папку, не содержащую имя файла, соответствующее glob / regex

Я хочу сделать следующее. У меня есть файловая иерархия глубины 2, например:

A
| B
| | g
| | h50000
| C

Где A, B, C - папки. Я хочу удалить все папки без файлов, соответствующих определенным шаблонам (в моем случае 50000 - шаблон, стиль глобуса) на уровне глубины 2. (В этом примере папку C следует удалить только вместе с ее содержимым, а A остается)

В моем приложении все в порядке, если я удалю все папки, в которых ни один из дочерних файлов не содержит имени файла, соответствующего шаблону. (Было бы проще не удалять A, не указав, на какой глубине я удаляю).

Как я смогу сделать это в bash на машине с Linux?

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

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

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

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

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


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

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

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

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

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

    while read line 
    do
    
       find . -wholename "$line" -delete
    
    done < deletable
    

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


В качестве альтернативы (и проще): если у вас есть root-доступ, временно измените i-атрибут, предотвращающий изменения, в том числе удаление, удалить все (так как удаление не разрешено для i-flagged files и dirs) и удалите 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 *