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

То, что Вы хотите использовать, является экраном или еще лучше удобной для пользователя оберткой вокруг экрана, названного byobu.

Экран позволяет Вам выполнять несколько сессий виртуального терминала на той же ssh сессии. Учебное руководство и страницы справки доступны.

byobu является оберткой, которая позволяет легко открывать новые экраны с простой функциональной клавишей вместо сочетания клавиш от ctrl-a. Это также показывает строку состояния со всеми открытыми виртуальными терминалами, которые можно назвать.

Другой хорошей функцией является то, что весь Ваш экран может не лечь спать, в то время как Ваше соединение SSH разъединяется. Вы просто соединяетесь снова через ssh и называете byobu, и все похоже прежде.

Наконец некоторые снимки экрана byobu.

154
02.03.2011, 00:08
7 ответов

Объединение GNU find опции и предикаты, эта команда должна сделать задание:

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

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

232
27.01.2020, 19:28
  • 1
    -delete уже подразумевает -depth таким образом, Вы не должны указывать это вручную. –  jamadagni 19.09.2014, 05:31
  • 2
    Спасибо, я не понял это. Ответ обновляется. попытка –  Christophe Drevet-Droguet 19.09.2014, 18:57
  • 3
    я добавил бы -mindepth 1 здесь, для препятствования удалить сам начальный каталог, если это было бы пусто. –  Greg Dubicki 20.08.2016, 15:49
  • 4
    Большой, но не работает над моими старыми хостами SunOS... –  dokaspar 08.08.2017, 13:05
  • 5
    ! имеет особое значение для оболочки. Необходимо выйти из него. Что-то как: \! -name 'Completed' незадолго до -delete должен работать. Или Вы просто помещаете файл маркера в этот каталог. –  Christophe Drevet-Droguet 02.04.2018, 11:34

Перечислите каталоги deeply-nested-first.

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. Спецификатор шарика F соответствия непустые каталоги, таким образом, /^F соответствия пустые каталоги. Каталоги, которые только содержат пустые каталоги, не могут быть подобраны так легко.

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

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

53
27.01.2020, 19:28
  • 1
    Вот именно. Вместо 90 секунд требуется 0,90 с. –  maaartinus 02.03.2011, 00:14
  • 2
    @maaartinus: мне любопытно: у Вас есть подобный набор данных, где Вы могли попробовать без -p? Я не думал бы, что это будет иметь значение. –  Gilles 'SO- stop being evil' 02.03.2011, 00:15
  • 3
    @maartinus — другая небольшая оптимизация: добавление -empty должен работать с этим (хотя я не уверен точно, сколько это получит). И очень, очень тривиально, так как Вы, вероятно, не хотите удалять ., использовать -mindepth 1. –  mattdm 02.03.2011, 00:19
  • 4
    Это не было удаление, но запуск процесса наверху, что взяло почти все время. Я пропустил -depth аргумент, который делает rmdir -p бесполезный. Я уже изменил свой комментарий. 90 с были моей исходной попыткой; нет ничего удивляющего здесь. –  maaartinus 02.03.2011, 00:20
  • 5
    я понял, что мы можем удалить rmdir управляйте звонят в целом, по крайней мере, с GNU находят, с этой командой: find . -depth -type d -empty -delete –  Christophe Drevet-Droguet 02.01.2014, 16:26

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

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

6
27.01.2020, 19:28

находят. -depth -type d -exec rmdir {} +

- самый простой и стандартный ответ на этот вопрос.

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

3
27.01.2020, 19:28
Команда

rm -r */у меня работала легко. rmдолжен требовать -fдля принудительного удаления каталогов с файлами. rm -rдолжен удалять только пустые каталоги. Я открыт для того, почему это может быть неправильно. Это также должно оставить файлы, так как */просматривает только папки.

-2
27.01.2020, 19:28

find. -type d -printf "%d %p\n" |\ sort -nr |\ perl -pe 's/^\d+\s//;' |\ while read dir; do \ (rmdir "$dir" > /dev/null 2>&1); \ done

Вот как это работает:

  1. Рекурсивный список всех каталогов вместе с их глубиной
  2. Сортировка по убыванию их глубины
  3. Отфильтровать только пути к каталогам
  4. Запустите rmdirв списке один за другим
0
27.01.2020, 19:28

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

Комментарии внутри .bashrc, чтобы я не забыл их позже, когда мне нужно будет это настроить.

# find empty directories
alias find-empty='find. -type d -empty'

# fine empty/zero sized files
alias find-zero='find. -type f -empty'

# delete all empty directories!
alias find-empty-delete='find-empty -delete'

# delete empty directories when `-delete` option is not available.
# output null character (instead of newline) as separator. used together
# with `xargs -0`, will handle filenames with spaces and special chars.
alias find-empty-delete2='find-empty -print0 | xargs -0 rmdir -p'

# alternative version using `-exec` with `+`, similar to xargs.
# {}: path of current file
# +: {} is replaced with as many pathnames as possible for each invocation.
alias find-empty-delete3='find-empty -exec rmdir -p {} +'

# for removing zero sized files, we can't de-dupe them automatically
# since they are technically all the same, so they are typically left
# beind. this removes them if needed.
alias  find-zero-delete='find-zero -delete'
alias find-zero-delete2='find-zero -print0 | xargs -0 rm'
alias find-zero-delete3='find-zero -exec rm {} +'
1
27.01.2020, 19:28

Теги

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