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

58

Скажем, у меня есть каталог с именем foo/. Эта папка содержит подкаталоги. Как я могу удалить все пустые каталоги в одной команде?

justingrif
источник

Ответы:

119

Попробуйте эту команду:

find . -empty -type d -delete

Команда findиспользуется для поиска файлов / каталогов, соответствующих определенным критериям поиска, по указанному пути, в данном случае в текущем каталоге (отсюда и в .).

-emptyВариант справедливо для любого файла и каталога , который пуст.

-type dВариант справедливо для файла типа , указанного; в данном случае dобозначает тип файла каталога .

-deleteОпция действие для выполнения, и справедливо для всех файлов , найденных в результате поиска.

Билл
источник
Я думаю, что это самый простой способ сделать это, поэтому я собираюсь пойти дальше и отметить это как ответ.
Justingrif
Привет, Билл, я попытался написать еще один похожий вопрос, и он не позволил мне, потому что там говорилось, что это было обманом, поэтому я надеялся, что ты сможешь ответить мне здесь. Скажем, я хотел сделать то же самое, что и выше, но удалить все каталоги, независимо от того, пусты они или нет.
justingrif
3
Как вы бы удалить каталоги, независимо от того , являются ли они пусты, введите следующую команду: rm -rf <directory-name>. Это удалит каталог вместе со всем его содержимым, включая файлы и подкаталоги. В -rозначает опция удаления рекурсивно, в то время как -fсредства команда не подскажите перед удалением. Однако если вы хотите получить запрос перед удалением каталога / файла, замените -fпараметр на -iпараметр.
Билл
Что делать, если в указанном каталоге было несколько файлов, которые я хотел сохранить. Итак, я хотел удалить все каталоги в / foo / bar /, но сохранить все файлы, которые могут быть там.
Justingrif
2
Это можно сделать, используя канал для подачи stdoutодной команды (например find) в stdinдругую (например rm), но будьте очень осторожны, так как это может уничтожить или удалить файлы / каталоги, которые вы не хотите удалять! Для получения дополнительной информации о том, как это сделать, см. manСтраницы для каждой из этих команд. Чтобы быть в безопасности, всегда проверяйте такие вещи во временном каталоге, прежде чем испытывать их на реальных вещах.
Билл
11

Вы можете воспользоваться rmdirотказом команды удалить непустые каталоги и find -depthопцией обхода дерева каталогов снизу вверх:

find . -depth -exec rmdir {} \;  

(и игнорировать ошибки), или добавить, 2>/dev/nullчтобы действительно игнорировать их.

-depthВозможность findначала находить в нижней части дерева каталогов.

rm -rfудалит все файлы в каталоге (и его подкаталогах, и ....) и все каталоги и все.

waltinator
источник
8
rmdir *

Удалит все пустые каталоги. Он выдаст ошибку для каждого непустого каталога и файла, чтобы эти ошибки не загромождали ваш терминал, используйте

rmdir * 2> /dev/null
evilsoup
источник
Это не подходит для сценариев, так как будет завершено с ненулевым кодом состояния, но это работает.
the_drow
@the_drow, как это делает неподходящим? Кстати, вы также можете использовать rmdir * 2>/dev/null || true. (Способ find (1) лучше подходит для сценариев, но по другой причине: потому что он лучше выражает то, что вы хотите сделать.)
Alois Mahdal
Я часто делаю это в $HOME. Со злой усмешкой
Алоис Махдал
Потому что он сообщит об ошибке, если некоторые каталоги не пусты.
the_drow
это быстрее, чем метод поиска? Кто-нибудь сравнивал эти два?
Xerus
1
find . -type d -empty -delete -maxdepth 1

Если вы хотите удалить только прямые подкаталоги foo/.

Саймон Баарс
источник
0

Подход Python

$ tree                                                                                                                                                                                  
.
├── empty_dir1
├── empty_dir2
├── subdir1
│   ├── file1.abc
│   └── file2.abc
└── subdir2
    ├── file1.abc
    └── file2.abc

4 directories, 4 files
$ python -c 'import os;empty=[r for r,s,f in os.walk(".") if not f and not s and r != "." ];map(lambda x: os.rmdir(x),empty)'
$ tree
.
├── subdir1
│   ├── file1.abc
│   └── file2.abc
└── subdir2
    ├── file1.abc
    └── file2.abc

Это работает так:

  • мы используем os.walk()функцию для рекурсивного обхода дерева каталогов. На каждой итерации rустанавливается текущая папка, к которой мы обращаемся, sсодержит список каталогов внутри rи fбудет содержать список файлов в этой папке. Конечно, если fи sпусто, мы знаем, что rпусто.
  • Первое понимание списка позволяет нам создать emptyсписок всех пустых каталогов на основе оценки, указанной выше.
  • вторая функция, map()используется для выполнения os.rmdir()каждого элемента в emptyсписке. Понимание списка может быть использовано как альтернатива.

Как сценарий это будет так:

#!/usr/bin/env python
import os
empty=[]
for r,s,f in os.walk("."):
    if not f and not s and r != ".":
        empty.append(r)

for i in empty:
    os.rmdir(i)
Сергей Колодяжный
источник
слишком сложно для
простых
@nurulhudamustaqim Зависит от точки зрения. Для многих пользователей Linux, которые привыкли к Python, это на самом деле очень скромно :) И помимо его разнообразия. Современное системное администрирование не ограничивается bash или /bin/shonly, а Python на самом деле более элегантный язык, чем эти два
Сергей Колодяжный