El comando 'ls -d' no muestra directorios. ¿Hay alguna manera de hacer que 'ls' solo muestre directorios en lugar de archivos y directorios?

44

¿Hay alguna manera de llegar lsa mostrar solo directorios en lugar de archivos y directorios?

Desde la página del manual:

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

Entonces, si lo escribo en el /directorio, espero ver solo directorios. En su lugar, muestra "."

$ cd /
$ ls -d
.

Esperaba ls -dmostrarme esto:

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

¿Hay alguna manera de llegar lsa mostrar solo directorios en lugar de archivos y directorios?

nelaaro
fuente
17
El lsd puede ser muy confuso.
boehj
2
@jin ls -d * / funciona. Pero, ¿por qué tengo que "* /" para obtener la salida que quiero?
nelaaro
8
@nelaar -dno significa enumerar solo directorios, significa no enumerar los contenidos del directorio. Intente escribir ls */y verá el contenido de todos los directorios.
Jin
2
He ldirdualizada a ls -d */en mi .bashrcpara hacer esto más fácil ...
DQdlM
1
Puedo darle toneladas de información, pero ni una sola bandera por solo mostrar directorios ...
DimiDak

Respuestas:

50

Sus expectativas se basan en DOS Think / Windows Think y están equivocadas. En MS-DOS, Windows y, de hecho, en algunos otros sistemas operativos IBM / Microsoft, la expansión de comodines se realiza mediante el comando en sí, y cosas como la /aopción del dircomando actúan como filtros de atributos durante la expansión de comodines. direxpande comodines como *, que el intérprete de comandos le pasa tal cual, y si /ase especifica, aplica los filtros apropiados a lo que se devuelve. (En algunos sistemas operativos, los filtros de atributos se pueden asignar a la llamada del sistema para enumerar un directorio y el núcleo del sistema operativo, o sus controladores del sistema de archivos, los aplica ellos mismos).

En Unices y en Linux, la expansión de comodines la realiza el shell y no tiene en cuenta los permisos. Cuando, en el directorio raíz, haces

ls *

lo que el lscomando mismo recibe del shell es (algo así como)

ls bin home opt var boot dev tmp etc perdido + encontrado root usr

Lo que hace la opción -d/ --directoryes desactivar lo que normalmente sucede después . Lo que normalmente sucede a continuación es que lsexamina cada uno de sus argumentos, ve que son directorios y decide enumerar sus contenidos. Para los argumentos que nombran archivos, simplemente imprime la información del archivo en sí. Con la -dopción, los directorios se tratan como archivos. Por lo tanto, lsimprime la información de cada uno de los directorios que se pasa como argumento, tal como lo haría si fueran archivos.

Por -d lo tanto, no es una opción de "imprimir solo directorios". De hecho, no solo no existe tal opción; No puede haber tal opción. La expansión de comodines se realiza mediante el shell, y ( shal menos en un POSIX ) no hay forma de decirle al shell que verifique los permisos y los bits de tipo de archivo cuando se expande *en una lista de nombres. Para obtener una lista de los nombres de los directorios solos, es necesario usar el findcomando, como se explica en ztank1013, o usar el truco de que un nombre de ruta que termina con una barra inclinada implica la entrada del directorio ., como se explica en Jin. ( JinEl truco termina con el lscomando recibiendo los argumentos

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

porque el patrón */de hecho hace coincidir los nombres de ruta con dos componentes, el segundo está vacío y, por lo tanto, no hace exactamente lo que deseaba. En particular, tratará los enlaces simbólicos que apuntan a directorios como si fueran directorios).

El comportamiento de ls -dsin a *es una simple extensión de lo anterior. Simplemente hay que saber una cosa más ls: cuando no se le dan argumentos, se supone un argumento predeterminado de .. Ahora sin la -dopción, el comportamiento antes mencionado conduce al contenido del directorio nombrado al .enumerarse y a mostrar la información de su contenido. Con la -dopción, el directorio .se trata como si fuera un archivo, y se muestra su propia información, en lugar de sus contenidos enumerados.

JdeBP
fuente
3
"no puede haber tal opción", es una afirmación bastante sólida, la implementación de dicha opción es obvia: vea un argumento que no sea de directorio e ignórelo. Lo que no se puede implementar es el equivalente a dir /s *.txt[sin recurrir a citar comodines como para encontrar]
Random832
66
Correcto, pero no hay una razón lógica por la que no pueda tener una opción que filtre los elementos que se pasaron como argumentos. El hecho de que "la expansión de comodines está separada de la comprobación de tipos de entrada" es irrelevante, ya que esto no tiene nada en absoluto que ver con la expansión de comodines - Sólo la comprobación de tipos de entrada, que no hay ninguna razón por la que no se puede hacer por completo dentro de ls. Si ls --color puede sombrearlos de azul, ls -F puede poner un / después de ellos, y ls -l puede poner una 'd' en el modo, entonces alguna otra opción hipotética podría omitirlos. Que tal opción no exista no significa que " no pueda ".
Random832
55
Random832 hace un punto decente: ls podría tener una opción para filtrar archivos o directorios, y esto no es mutuamente exclusivo con hacer que el shell se expanda. No hay condición de carrera dentro de ls: puede filtrarlo ya que registra los archivos normalmente. (Ya existe una carrera entre la expansión de shell y ls, FWIW). Creo que la expansión de shell es solo una parte de la razón: la expansión de shell (y el filtrado en general) no se implementa en ls porque debería implementarse nuevamente en cp , mv, etc. Unix es un "haz una cosa y hazlo bien". Si necesita filtrado avanzado, hay herramientas para eso.
Thanatos
2
La ls -popción agrega un /símbolo solo a los directorios. No hay ninguna razón para no extender las capacidades de impresión de salida con algo que solo produzca estos (en lugar de ls -p | grep /).
Anne van Rossum
3
@JdeBP, los ataques ad-hominem ("kiddo") y la arrogancia (todos excepto usted no conocen "los fundamentos de Unix") no pertenecen a una discusión técnica. Además, se está volviendo loco cuando argumenta que una opción de comando no puede controlar la expansión de comodines realizada por shell. ¡Por supuesto que no puede! Ni Random832, ni Thanatos, ni Anne van Rossum, y ni siquiera la pregunta en sí mencionan comodines de ninguna manera. La objeción era que esa ls --only-directories .opción podría agregarse lseventualmente.
mkalkov
30

Puede usar ls -d */, o ls -d .*/para directorios ocultos.

Jin
fuente
truco inteligente usando el /!
Mono
Si esto es bueno ¿Hay algún caso donde esto no funciona?
iyrin
55
+1 por proporcionar la respuesta en una línea. Supongo que la respuesta aceptada también la tiene, en algún lugar.
Calculus Knight
¿Cómo puede usar esto en un script sin estar ya en el directorio?
DimiDak
13

Prueba esto

 find . -mindepth 1 -maxdepth 1 -type d

para obtener solo directorios bajo su ubicación actual.

ztank1013
fuente
5

También podría gustarte

tree -d 

que enumera perfectamente todos los directorios y subdirectorios con una representación gráfica de la estructura de árbol.

fuenfundachtzig
fuente
3
Y solo para un nivel profundo:tree -dL 1
Anne van Rossum
Desafortunadamente no puedes combinar mucho con el árbol. # tree -d | grep wc -l (entrada estándar)
DimiDak
5

Si desea ver directorios solo con detalles como la ls -lopción (ELL), puede usar a continuación:

find -maxdepth 1 -type d -ls;

Lo anterior solo le dará los detalles como obtiene con la -lopción.

Adnan Bhatti
fuente
1
Puede ser incluso mejor usar find -maxdepth 1 -type d -exec ls -d {} +para obtener la salida en el lsformato habitual .
mkalkov
4

Si desea realizar el trabajo de otra manera, intente esto:

ls -l | grep ^d

Aunque una sola herramienta es suficiente en esta situación. La tubería siempre está ahí para ayudarlo. Me gusta la flexibilidad en Linux, que deseo que hagas.

Bohr
fuente
1
Esto va a filtrar más que directorios.
ocodo
2
@Slomojo, esto filtrará todo menos los directorios. ¿Qué querías decir?
mkalkov
Sí, necesitas el -l (largo) para que los permisos encabecen la línea. "d" para el directorio. Además, obtienes una lista "larga" de una entrada de directorio que es agradable.
geoO
1

Espero que esto rectifique tu necesidad. El siguiente comando enumerará solo los directorios en una ruta determinada.

ls -F <path> | grep /

Ejemplo:

ls -F ~ | grep /
Thiyagu ATR
fuente