La commande 'ls -d' n'affiche pas les répertoires. Existe-t-il un moyen d'obtenir que 'ls' affiche uniquement les répertoires au lieu des fichiers et des répertoires?

44

Est-il possible d’ lsafficher uniquement des répertoires au lieu de fichiers et de répertoires?

De la page de manuel:

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

Donc, si je le tape dans le /répertoire, je m'attends à ne voir que des répertoires. Au lieu de cela, il montre "."

$ cd /
$ ls -d
.

Je m'attendais ls -dà me montrer ceci:

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

Est-il possible d’ lsafficher uniquement des répertoires au lieu de fichiers et de répertoires?

Nelaaro
la source
17
LSD peut être très déroutant.
boehj
2
@jin ls -d * / works. Mais pourquoi dois-je "* /" pour obtenir le résultat que je veux.
Nelaaro 10/10
8
@nelaar -dne veut pas dire lister seulement les répertoires, cela veut dire ne pas lister le contenu des répertoires. Essayez de taper ls */et vous verrez le contenu de tous les répertoires.
Jin
2
Je ldirlisé à ls -d */mon .bashrcpour vous faciliter la tâche ...
DQdlM
1
Je peux vous donner des tonnes d’informations, mais pas un seul drapeau pour montrer seulement des annuaires ...
DimiDak

Réponses:

50

Vos attentes sont basées sur DOS Think / Windows Think et sont fausses. Sur MS-DOS, Windows et même sur quelques autres systèmes d'exploitation IBM / Microsoft, le développement des caractères génériques est effectué par la commande elle-même. Des éléments tels que l' /aoption de la dircommande agissent comme des filtres d'attributs lors du développement des caractères génériques. dirétend les caractères génériques tels que ceux *que l'interpréteur de commande lui transmet tels quels, et si /aspécifié, il applique les filtres appropriés à ce qui est renvoyé. (Sur certains systèmes d'exploitation, les filtres d'attributs peuvent être attribués à l'appel système pour énumérer un répertoire et le noyau du système d'exploitation, ou ses pilotes de système de fichiers, les applique eux-mêmes.)

Sous Unices et Linux, l’extension des caractères génériques est effectuée par le shell et n’est pas liée aux autorisations. Quand, dans le répertoire racine, vous faites

ls *

ce que la lscommande elle-même reçoit du shell (quelque chose comme)

ls bin accueil opt var démarrage dev tmp etc perdu + racine trouvée usr

L’ option -d/ désactive ce qui se passe normalement ensuite . Ce qui se passe ensuite ensuite, c’est que chacun de ses arguments est examiné, qu’il s’agit de répertoires et qu’il décide d’énumérer son contenu. Pour les arguments qui nomment des fichiers, il n’imprime que les informations relatives au fichier lui-même. Avec l' option, les répertoires sont traités comme des fichiers. Donc, imprime les informations pour chacun des répertoires qui sont passées en tant qu'arguments, exactement comme s'il s'agissait de fichiers.--directoryls-dls

Donc, ce -d n'est pas une option "imprimer uniquement les répertoires". En fait, non seulement cette option n’existe pas; il ne peut y avoir une telle option. L’exploitation des caractères génériques est effectuée par le shell et (dans un POSIX shau moins), il n’ya aucun moyen de demander au shell de vérifier les bits d’autorisation et de type de fichier lorsqu’il se développe *dans une liste de noms. Pour obtenir une liste des noms de répertoires uniquement, il est nécessaire d'utiliser la findcommande, comme expliqué par ztank1013ou d'utiliser le truc selon lequel un chemin d'accès se terminant par une barre oblique implique l'entrée du répertoire ., comme expliqué par Jin. ( JinL'astuce finit avec la lscommande recevant les arguments

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

parce que le modèle */fait en réalité correspondre les chemins d'accès avec deux composants, le second étant vide, et ne fait donc pas tout à fait ce qui était souhaité. En particulier, les liens symboliques pointant vers des répertoires seront traités comme s'il s'agissait de répertoires.)

Le comportement de ls -dsans *est une simple extension de ce qui précède. Il suffit simplement de savoir une dernière chose à propos de ls: quand aucun argument n’est donné, cela suppose un argument par défaut de .. Désormais, sans cette -doption, le comportement susmentionné conduit au contenu du répertoire nommé par .énumération et à l'affichage des informations relatives à son contenu. Avec l' -doption, le répertoire .est traité comme s'il s'agissait d'un fichier et ses propres informations sont affichées, plutôt que son contenu énuméré.

JdeBP
la source
3
"il ne peut y avoir une telle option" - c'est une affirmation assez forte - la mise en œuvre d'une telle option est évidente: voyez un argument autre qu'un répertoire et ignorez-le. Ce qui ne peut pas être mis en œuvre équivaut à dir /s *.txt[sans recourir à des guillemets génériques pour trouver]
Random832
6
Bien, mais il n’ya aucune raison logique que je ne puisse pas avoir d’option permettant de filtrer les éléments passés en arguments. Le fait que "l'expansion du caractère générique soit dissociée de la vérification du type d'entrée" est sans importance, car cela n'a rien à voir avec la vérification du type d'entrée avec caractère générique, pour laquelle il n'y a aucune raison que cela ne puisse pas être fait entièrement dans ls. Si ls --color peut les ombrer de bleu, ls -F peut mettre un / après eux, et ls -l peut mettre un 'd' dans le mode, alors une autre option hypothétique pourrait les omettre. Le fait qu'une telle option n'existe pas ne signifie pas qu'il " ne peut pas ".
Random832
5
Random832 fait un bon point: ls pourrait avoir une option pour filtrer les fichiers ou les répertoires, et cela ne s’exclut pas mutuellement avec le développement du shell. Il n'y a pas de condition de concurrence dans ls: il peut le filtrer car il statistiques normalement les fichiers. (Il y a déjà une course entre le shell shell et ls, FWIW.) Je pense que l'expansion du shell n'est qu'une partie de la raison: l'expansion du shell (et le filtrage en général) n'est pas implémentée dans ls car elle devrait être implémentée à nouveau dans cp , mv, etc. Unix est un "faire une chose et bien le faire". Si vous avez besoin d'un filtrage avancé, il existe des outils pour cela.
Thanatos
2
L' ls -poption ajoute un /symbole aux répertoires uniquement. Il n'y a aucune raison de ne pas étendre les capacités d'impression de sortie avec quelque chose qui ne produit que celles-ci (plutôt que ls -p | grep /).
Anne van Rossum
3
@JdeBP, les attaques ad-hominem ("kiddo") et l'arrogance (tout le monde à l'exception de vous ne connaissent pas "les principes fondamentaux d'Unix") n'appartiennent pas à une discussion technique. En outre, vous tirez un homme de paille lorsque vous affirmez qu'une option de commande ne peut pas contrôler le développement de caractères génériques effectué par shell. Bien sûr, ça ne peut pas! Ni Random832, ni Thanatos, ni Anne van Rossum, et même la question elle-même ne mentionnent aucun caractère générique. L'objection était que cette ls --only-directories .option pourrait éventuellement être ajoutée ls.
mkalkov
30

Vous pouvez utiliser ls -d */ou ls -d .*/pour les répertoires cachés.

Jin
la source
astuce intelligente en utilisant le /!
Mono
Ouais c'est bien. Y a-t-il un cas où cela ne fonctionne pas?
Iyrin
5
+1 pour fournir la réponse sur une ligne. Je suppose que la réponse acceptée l’a aussi, quelque part.
Calculus Knight le
Comment pouvez-vous utiliser ceci dans un script sans être déjà dans le répertoire?
DimiDak
13

Essaye ça

 find . -mindepth 1 -maxdepth 1 -type d

pour obtenir uniquement des répertoires sous votre emplacement actuel.

ztank1013
la source
5

vous pourriez aussi aimer

tree -d 

qui répertorie proprement tous les répertoires et sous-répertoires avec une représentation graphique de la structure arborescente.

Fuenfundachtzig
la source
3
Et pour un seul niveau de profondeur:tree -dL 1
Anne van Rossum
Malheureusement, vous ne pouvez pas beaucoup combiner avec l'arbre. # arbre -d | grep wc -l (entrée standard)
DimiDak
5

Si vous voulez voir uniquement les répertoires avec des détails comme l' ls -loption (ELL), vous pouvez utiliser ci-dessous:

find -maxdepth 1 -type d -ls;

Vous trouverez ci-dessus uniquement les détails que vous obtenez avec l' -loption.

Adnan Bhatti
la source
1
Il peut même être préférable d’utiliser find -maxdepth 1 -type d -exec ls -d {} +pour obtenir une sortie au lsformat habituel .
mkalkov
4

Si vous voulez faire le travail d'une autre manière, essayez ceci:

ls -l | grep ^d

Bien qu'un seul outil soit suffisant dans cette situation. Pipe Line est toujours là pour vous aider. J'aime la flexibilité sous Linux, ce que je vous souhaite.

Bohr
la source
1
Cela va filtrer plus que des répertoires.
octobre
2
@ Slomojo, cela filtrera tout sauf les répertoires. Que voulais-tu dire?
mkalkov
Oui, vous avez besoin de -l (long) pour que les autorisations arrivent en tête. "d" pour le répertoire. De plus, vous obtenez une liste "longue" d’une entrée de répertoire qui est agréable.
geoO
1

J'espère que cela rectifiera votre besoin. La commande ci-dessous ne listera que les répertoires d'un chemin donné.

ls -F <path> | grep /

Exemple:

ls -F ~ | grep /
Thiyagu ATR
la source