Команда '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до лише каталогів, що відображаються, а не файлів і каталогів?


17
lsd може бути дуже заплутаним.
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команди, виконуються як фільтри атрибутів під час розширення wildcard. dirрозширює символи, подібні до того *, що інтерпретатор команд передає йому як є, і якщо /aвказано, він застосовує відповідні фільтри до поверненого. (У деяких операційних системах фільтри атрибутів можуть бути надані системному виклику для перерахування каталогу, а ядро ​​операційної системи або його драйвери файлової системи застосовує їх самі.)

У Unices і на Linux розширення підстановки здійснюється оболонкою і не враховує дозволів. Коли в кореневому каталозі ви робите

ls *

те, що lsсама команда отримує з оболонки (щось на зразок)

ls bin home opt var boot dev tmp тощо загублений + знайдений root usr

Що робить -d/ --directoryваріант, це вимкнути те, що зазвичай відбувається далі . Що зазвичай відбувається далі, це те, що lsпереглядає по черзі кожен з його аргументів, бачить, що вони є каталогами, і вирішує перерахувати їх зміст. Для аргументів, які називають файли, він просто виводить інформацію для самого файлу. За допомогою -dпараметра каталоги трактуються так само, як файли. Тому lsдрукується інформація для кожного із каталогів, яка передається як її аргументи, так само, як це було б, якби вони були файлами.

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

ls bin / home / opt / var / boot / dev / tmp / тощо / загублений + знайдений / root / usr /

оскільки модель */насправді відповідає іменам шляхів з двома компонентами, другий - порожнім, і тому не зовсім робить те, що було бажано. Зокрема, він буде ставитися до символьних посилань, що вказують на каталоги так, ніби вони є каталогами.

Поведінка ls -dбез а *є простим продовженням вищезазначеного. Потрібно просто знати ще одне про те ls: Коли йому не дано аргументів, він приймає аргумент за замовчуванням .. Тепер без на -dвиборі, згадане вище поведінка призводить до змісту каталогу названого .бути перераховані і інформація для його змісту відображається. За допомогою -dпараметра до каталогу .поводиться так само, як якщо б це був файл, і відображається його власна інформація, а не перераховується його вміст.


3
"не може бути такої опції" - це досить сильне твердження - реалізація такого варіанту очевидна: див. аргумент без каталогу та ігноруй його. Що неможливо реалізувати, це еквівалент dir /s *.txt[не вдаючись до цитування шаблонів, як для знаходження]
Random832

6
Правильно, але немає ніякої логічної причини, щоб у ls не було можливості, яка б фільтрувала елементи, передані як аргументи. Той факт , що «підстановочні розширення відривається від перевірки типу записи» не має ніякого значення, так як це не має нічого взагалі робити з розширенням підстановлювальний - тільки типом входу перевіркою, що немає причин не може бути зроблено повністю в Ls. Якщо ls -color може відтінити їх синіми, ls -F може поставити a / після них, а ls -l може поставити 'd' в режим, то деякі інші гіпотетичні варіанти можуть їх опустити. Те, що такий варіант не існує, не означає, що він " не може ".
Випадково832

5
Random832 є гідним моментом: ls може мати можливість фільтрувати файли чи каталоги, і це не є взаємовиключним з розширенням оболонки. У межах ls немає перегонового стану: він може фільтрувати його, як він нормально записує файли. (Уже є гонка між розширенням оболонки та ls, FWIW.) Я думаю, що розширення оболонки є лише частиною причини: розширення оболонки (і фільтрація в цілому) не реалізовано в ls, оскільки її потрібно було б знову реалізувати в cp , mv тощо. Unix - це "зроби одну справу і зроби це добре". Якщо вам потрібна розширена фільтрація, є інструменти для цього.
Танатос

2
ls -pОпція додає /символ тільки до каталогам. Немає ніяких причин не розширювати можливості друку на виході тим, що робить їх лише (а не ls -p | grep /).
Енн ван Россум

3
@JdeBP, атаки ad hominem ("kiddo") та зарозумілість (усі, крім вас, не знають "основи Unix") не належать до технічної дискусії. Крім того, ви стягуєте солом’яного чоловіка, коли ви стверджуєте, що командний параметр не може контролювати розширення підстановки, зроблене оболонкою. Звичайно, це не може! Ні Random832, ні Танатос, ні Енн ван Россум, і навіть саме питання жодним чином не згадують про підстановку. Заперечення було те, що ls --only-directories .варіант може бути доданий до lsкінця.
mkalkov

30

Ви можете використовувати ls -d */або ls -d .*/для прихованих каталогів.


розумний трюк за допомогою /!
Моно

Так, це добре. Чи є випадок, коли це не працює?
iyrin

5
+1 для надання відповіді в одному рядку. Я здогадуюсь, що прийнята відповідь також є десь.
Лицар обчислення

Як ви можете використовувати це в сценарії, не маючи вже в каталозі?
DimiDak

13

Спробуйте це

 find . -mindepth 1 -maxdepth 1 -type d

щоб отримати лише каталоги під поточним місцеположенням.


5

Можливо, вам також сподобається

tree -d 

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


3
І лише на один рівень глибокий:tree -dL 1
Енн ван Россум

На жаль, ти не можеш багато поєднати з деревом. # дерево -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, це відфільтрує все, крім каталогів. Що ти мав на увазі?
mkalkov

Так, вам потрібен -l (довгий), щоб дозволи очолювали лінію. "d" для каталогу. Крім того, ви отримуєте "довгий" перелік запису каталогів, що приємно.
геоО

1

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

ls -F <path> | grep /

Приклад:

ls -F ~ | grep /
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.