Как удалить все пустые каталоги в поддереве?

Как удалить все пустые каталоги в поддереве? Я использовал что-то вроде

find . -type d -exec rmdir {} 2>/dev/null \; 

но мне нужно запускать несколько раз, чтобы удалить только каталоги, содержащие только пустые каталоги. Более того, это довольно медленно, особенно под cygwin.

  • Найти файлы дубликатов файлов и заглавные буквы rm
  • Удалять все файлы рекурсивно, не удаляя каталоги
  • Команда rm в скрипте bash не работает с переменной
  • Команда AIX 'rm' не имеет параметра '-v' для подробного вывода
  • удалить каталог со специальным символом в имени файла
  • Как процитировать аргументы с помощью xargs
  • Алиасирование `rm` для создания CLI" корзины "
  • Что делать после отмены «rm -rf / usr /» на Arch?
  • 4 Solutions collect form web for “Как удалить все пустые каталоги в поддереве?”

    Комбинируя параметры find и предикаты GNU, эта команда должна выполнять следующее задание:

     find . -type d -empty -delete 
    • -type d ограничивает каталоги
    • -empty ограничивает пустые
    • -delete удаляет каждую директорию

    Дерево идет от листьев без необходимости указывать -depth как это подразумевается -delete .

    Перечислите каталоги глубоко вложенные – сначала.

     find . -depth -type d -exec rmdir {} \; 2>/dev/null 

    (Обратите внимание, что перенаправление применяется к команде find в целом, а не только к rmdir . Перенаправление только для rmdir приведет к значительному замедлению, так как вам потребуется вызвать промежуточную оболочку.)

    Вы можете избежать запуска rmdir в непустых каталогах, передав -empty предикат для поиска. GNU находит тесты в каталоге, когда он собирается запустить команду, поэтому будут удалены каталоги, которые только что были опустели.

     find . -depth -type d -empty -exec rmdir {} \; 

    Еще один способ ускорить – группировать вызовы rmdir . Оба они, вероятно, будут заметно быстрее оригинала, особенно в Cygwin. Я не ожидаю большой разницы между этими двумя.

     find . -depth -type d -print0 | xargs -0 rmdir 2>/dev/null find . -depth -type d -exec rmdir {} + 2>/dev/null 

    Какой метод быстрее, зависит от того, сколько у вас непустых каталогов. Вы не можете комбинировать- -empty методы для группировки вызовов, потому что тогда каталоги, содержащие только пустые каталоги, не будут пустым к тому времени, когда find по ним будет выглядеть.

    Другим методом было бы запустить несколько проходов. Будет ли это быстрее, зависит от многих вещей, в том числе, может ли целая иерархия каталогов оставаться в кеше диска между find запусками.

     while [ -n "$(find . -depth -type d -empty -print -exec rmdir {} +)" ]; do :; done 

    Альтернативно, используйте zsh. Квалификатор glob F соответствует непустым каталогам, поэтому /^F соответствует пустым каталогам. Каталоги, содержащие только пустые каталоги, не могут быть легко сопоставлены.

     while rmdir **/*(/N^F); do :; done 

    (Это завершается, когда rmdir получает пустую командную строку.)

    Если вы просто наложите -p на свой rmdir , это будет работать за один проход. Это не будет красивым или оптимальным, но он должен получить все. Это сообщает rmdir об удалении любых непустых родительских каталогов того, который вы удаляете.

    Вы можете немного сэкономить, добавив -empty тест, чтобы найти, поэтому он не беспокоится о непустых каталогах.

    find . -depth -type d -exec rmdir {} +

    является самым простым и стандартным ответом на этот вопрос.

    Другие ответы, приведенные здесь, к сожалению, зависят от специфических для вендора усовершенствований, которые не существуют во всех системах.

    Linux и Unix - лучшая ОС в мире.