Команда 'ls -d' не отображает каталоги. Есть ли способ заставить 'ls' отображать только каталоги, а не файлы и каталоги?

44

Есть ли способ получить lsтолько отображение каталогов вместо файлов и каталогов?

Со страницы руководства:

   -d, --directory
          list directory entries instead of contents, and do not  derefer
          ence symbolic links

Поэтому, если я наберу его в /каталоге, я ожидаю увидеть только каталоги. Вместо этого он показывает "."

$ cd /
$ ls -d
.

Я ожидал ls -dпоказать мне это:

$ ls -d
bin    data  home        opt    sbin  sys      var
boot   dev   lib         media  proc  selinux  tmp
cdrom  etc   lost+found  mnt    root  srv      usr

Есть ли способ получить lsтолько отображение каталогов вместо файлов и каталогов?

nelaaro
источник
17
ЛСД может быть очень запутанным.
Boehj
2
@jin ls -d * / работает. Но почему я должен "* /" получить желаемый результат?
nelaaro
8
@nelaar - -dэто не только список каталогов, но и не список содержимого каталогов. Попробуйте набрать, ls */и вы увидите содержимое всех каталогов.
Джин
2
Я ldiralised , чтобы ls -d */в моем , .bashrcчтобы сделать это проще ...
DQdlM
1
ls может дать вам тонны информации, но не один флажок только для показа каталогов ...
DimiDak

Ответы:

50

Ваши ожидания основаны на DOS Think / Windows Think и ошибочны. В MS-DOS, Windows и некоторых других операционных системах IBM / Microsoft расширение по шаблону выполняется самой командой, а такие /aпараметры, как опция dirкоманды, действуют как фильтры атрибутов при расширении по шаблону. dirрасширяет символы подстановки, например *, которые интерпретатор команд передает ему как есть, и, если /aуказано, применяет соответствующие фильтры к возвращаемому. (В некоторых операционных системах фильтры атрибутов могут быть переданы системному вызову для перечисления каталога, и ядро ​​операционной системы или драйверы его файловой системы применяют их самостоятельно.)

В Unices и в Linux расширение подстановочных знаков выполняется оболочкой и не учитывает разрешения. Когда в корневом каталоге вы делаете

ls *

что сама lsкоманда получает от оболочки (что-то вроде)

ls bin home opt var boot dev tmp и т. д. lost + found root usr

Что -d/ --directoryопция делает отключить то , что обычно происходит дальше . Что обычно происходит дальше, так это то ls, что он по очереди просматривает каждый из его аргументов, видит, что они являются каталогами, и решает перечислить их содержимое. Для аргументов, которые называют файлы, он просто выводит информацию для самого файла. С этой -dопцией каталоги обрабатываются как файлы. Поэтому lsвыводит информацию для каждого из каталогов, которая передается в качестве аргументов, так же, как если бы они были файлами.

Так что -d это не опция «только для печати каталогов». На самом деле такой возможности нет; не может быть такой возможности. Расширение с подстановочными знаками выполняется оболочкой, и ( shпо крайней мере, в POSIX ) нет способа указать оболочке проверять биты прав доступа и типов файлов при развертывании *в список имен. Чтобы получить список только имен каталогов, необходимо либо использовать findкоманду, как объяснено ztank1013, либо использовать хитрость, заключающуюся в том, что имя пути, заканчивающееся косой чертой, подразумевает запись каталога ., как объяснено Jin. ( Jinтрюк заканчивается тем, что lsкоманда получает аргументы

ls bin / home / opt / var / boot / dev / tmp / etc / lost + found / root / usr /

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

Поведение ls -dбез *является простым продолжением вышесказанного. Нужно просто знать еще одну вещь ls: когда ему не дают аргументов, он принимает аргумент по умолчанию .. Теперь без этой -dопции вышеупомянутое поведение приводит к тому, что содержимое каталога, названного путем .перечисления, и информация для его содержимого отображаются. С помощью этой -dопции каталог .обрабатывается так же, как если бы это был файл, и отображается его собственная информация, а не перечисленное содержимое.

JdeBP
источник
3
« такой опции быть не может», - это довольно сильное утверждение, - реализация такой опции очевидна: посмотрите на не-директивный аргумент и проигнорируйте его. То, что не может быть реализовано, является эквивалентом dir /s *.txt[без обращения к кавычкам, как при поиске]
Random832 10.10.11
6
Правильно, но нет логической причины, по которой у ls не может быть опции, которая отфильтровывает элементы, переданные в качестве аргументов. Тот факт , что «подстановочные расширение отрывается от проверки типа записи» не имеет никакого значения, так как это не имеет ничего вообще делать с расширением подстановочным - только типом входа проверкой, что нет причин не может быть сделаны полностью в Ls. Если ls --color может затенять их синим, ls -F может поставить / после них, а ls -l может поставить 'd' в режиме, то некоторые другие гипотетические опции могут их пропустить. То, что такой опции не существует, не означает, что она « не может ».
Random832 10.10.11
5
Random832 делает приличное замечание: ls может иметь возможность фильтровать файлы или каталоги, и это не является взаимоисключающим условием расширения оболочки. Внутри ls нет условия гонки: он может фильтровать его, как обычно, для файлов. (Между расширением оболочки и ls, FWIW уже есть гонка.) Я думаю, что расширение оболочки - это только часть причины: расширение оболочки (и фильтрация в целом) не реализовано в ls, потому что его нужно будет снова реализовать в cp Unix - это "делай одно и делай это хорошо". Если вам нужна расширенная фильтрация, для этого есть инструменты.
Танатос
2
ls -pОпция добавляет /символ только к каталогам. Нет никаких причин не расширять возможности печати с помощью чего-то, что только выводит их (а не ls -p | grep /).
Анна ван Россум
3
@JdeBP, атаки ad-hominem («kiddo») и высокомерие (все, кроме вас, не знают «основ Unix»), не относятся к техническим дискуссиям. Кроме того, вы тянете соломенного чучела, когда утверждаете, что параметр команды не может контролировать расширение подстановочных знаков, выполняемое оболочкой. Конечно, не может! Ни Random832, ни Thanatos, ни Anne van Rossum, ни даже сам вопрос не упоминают подстановочные знаки в любом случае. Возражение было то, что ls --only-directories .вариант может быть добавлен в lsконечном итоге.
Мкалков
30

Вы можете использовать ls -d */или ls -d .*/для скрытых каталогов.

Jin
источник
хитрый трюк с помощью /!
Mono
Да, это хорошо. Есть ли случай, когда это не работает?
Айрин
5
+1 за предоставление ответа в одну строку. Я предполагаю, что принятый ответ тоже где-то есть.
Исчисление Рыцарь
Как вы можете использовать это в сценарии, не находясь уже в каталоге?
ДимиДак
13

Попробуй это

 find . -mindepth 1 -maxdepth 1 -type d

чтобы получить только каталоги под вашим текущим местоположением.

ztank1013
источник
5

Вам также может понравиться

tree -d 

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

fuenfundachtzig
источник
3
И только на один уровень глубины:tree -dL 1
Анна Ван Россум
К сожалению, вы не можете много сочетать с деревом. # tree -d | grep wc -l (стандартный ввод)
DimiDak
5

Если вы хотите видеть каталоги только с подробной информацией, такой как ls -l(ELL), то вы можете использовать ниже:

find -maxdepth 1 -type d -ls;

Выше будет только дать вам детали, как вы получаете с -lопцией.

Аднан Бхатти
источник
1
Может быть даже лучше использовать, find -maxdepth 1 -type d -exec ls -d {} +чтобы получить вывод в обычном lsформате.
Мкалков
4

Если вы хотите выполнить работу по-другому, попробуйте это:

ls -l | grep ^d

Хотя в этой ситуации достаточно одного инструмента. Трубопровод всегда рядом, чтобы помочь вам. Мне нравится гибкость в Linux, которую я желаю вам сделать.

Бор
источник
1
Это собирается отфильтровать больше, чем каталоги.
ocodo
2
@Slomojo, это отфильтрует все, кроме каталогов. Что ты имел в виду?
Мкалков
Да, вам нужен ключ -l (long), чтобы права доступа были выше. «d» для каталога. Кроме того, вы получаете «длинный» список записей каталога, что приятно.
GeoO
1

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

ls -F <path> | grep /

Пример:

ls -F ~ | grep /
Тиягу ATR
источник