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?
С помощью find
вы можете исключить шаблон:
find \! -name '*50000*' -delete
Экранирование !
необходимо из-за его использования в оболочках.
Каталоги с содержимым не будут удалены.
ВНИМАНИЕ: поскольку из вашего вопроса мне это немного неясно - это БУДЕТ удалять другие файлы в папках, которые имеют шаблон 50000
, например A / B / g
будут удалены, и будут сохранены только файлы (и каталоги) с именем 50000
(включая их родительские каталоги)!
Для удаления всех каталогов, у которых нет 50000
файл в них и хранить каталоги с такими файлами вместе с другим содержимым этого каталога, я бы предложил двухэтапный метод:
перечислить все файлы и каталоги и сохранить в текстовый файл
находить . -depth -mindepth 1> все
список каталогов, которые необходимо сохранить (только найти файл и распечатать каталог)
найти. -depth -name '* 50000 *' printf '% h \ n'> сохранить
выберите удаляемые файлы и каталоги с помощью перевернутого grep
grep -vf keep all> deletable
использовать этот список для удаления (просто образец)
при чтении строки
делать
находить . -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 *