Pregunta Listado de directorios usando ls en bash: un examen


Este comando enumera directorios en la ruta actual: ls -d */

¿Qué es exactamente el patrón? */ ¿hacer?

¿Y cómo podemos dar la ruta absoluta en el comando anterior (p. ls -d /home/alice/Documents) para listar solo directorios en esa ruta?


702
2018-01-16 06:07


origen


Respuestas:


*/ es un patrón que coincide con todos los subdirectorios en el directorio actual (* coincidiría con todos los archivos y subdirectorios; el / lo restringe a los directorios). Del mismo modo, para enumerar todos los subdirectorios en / home / alice / Documents, use ls -d /home/alice/Documents/*/


743
2018-01-16 06:11



Cuatro formas de hacerlo, cada una con un formato de salida diferente

1. Usando echo

Ejemplo: echo */, echo */*/
Esto es lo que obtuve:

cs/ draft/ files/ hacks/ masters/ static/  
cs/code/ files/images/ static/images/ static/stylesheets/  

2. Usando ls solamente

Ejemplo: ls -d */
Aquí es exactamente lo que obtuve:

cs/     files/      masters/  
draft/  hacks/      static/  

O como lista (con información detallada): ls -dl */ 

3. Usando ls y grep

Ejemplo: ls -l | grep "^d" Esto es lo que obtuve:

drwxr-xr-x  24 h  staff     816 Jun  8 10:55 cs  
drwxr-xr-x   6 h  staff     204 Jun  8 10:55 draft  
drwxr-xr-x   9 h  staff     306 Jun  8 10:55 files  
drwxr-xr-x   2 h  staff      68 Jun  9 13:19 hacks  
drwxr-xr-x   6 h  staff     204 Jun  8 10:55 masters  
drwxr-xr-x   4 h  staff     136 Jun  8 10:55 static  

4. Bash Script (No se recomienda para el nombre de archivo contener espacio).

Ejemplo: for i in $(ls -d */); do echo ${i%%/}; done
Esto es lo que obtuve:

cs  
draft  
files  
hacks  
masters  
static

Si desea tener '/' como carácter final, el comando será: for i in $(ls -d */); do echo ${i}; done

cs/  
draft/  
files/  
hacks/  
masters/  
static/

379
2018-06-09 12:21



Yo suelo:

ls -d */ | cut -f1 -d'/'

Esto crea una sola columna sin barra posterior, útil en las secuencias de comandos.

Mis dos centavos.


74
2018-02-27 15:19



Para todas las carpetas sin subcarpetas:

find /home/alice/Documents -maxdepth 1 -type d

Para todas las carpetas con subcarpetas:

find /home/alice/Documents -type d

40
2017-07-23 08:30



4 (más) Opciones confiables.

Un no cotizado asterisco * será interpretado como un patrón (glob) por el caparazón.
El shell lo usará en la expansión del nombre de ruta.
 Luego generará una lista de nombres de archivos que coinciden con el patrón.
 Un asterisco simple coincidirá con todos los nombres de archivo en el PWD (presente directorio de trabajo).
Un patrón más complejo como */ coincidirá con todos los nombres de archivos que terminan en /.
 Por lo tanto, todos los directorios. Es por eso que el comando:

1.- eco.

echo */
echo ./*/              ### avoid misinterpreting filenames like "-e dir"

se expandirá (por el shell) a echo todos los directorios en el PWD.


Para probar esto: crea un directorio (mkdir) llamado como test-dir, y cd en ello:

mkdir test-dir; cd test-dir

Crea algunos directorios:

mkdir {cs,files,masters,draft,static}   # safe directories.
mkdir {*,-,--,-v\ var,-h,-n,dir\ with\ spaces}  # some a bit less secure.
touch -- 'file with spaces' '-a' '-l' 'filename'    # and some files:

El comando echo ./*/ seguirá siendo confiable incluso con archivos con nombre impar:

./--/ ./-/ ./*/ ./cs/ ./dir with spaces/ ./draft/ ./files/ ./-h/
./masters/ ./-n/ ./static/ ./-v var/

Pero los espacios en los nombres de archivo hacen que la lectura sea un poco confusa.


Si en lugar de echo, usamos ls, el shell sigue siendo lo que está expandiendo la lista de nombres de archivos. El shell es la razón para obtener una lista de directorios en el PWD. los -d opción de ls lo hace listar la entrada del directorio actual en lugar de los contenidos de cada directorio (como se presenta por defecto).

ls -d */

Sin embargo, este comando es (algo) menos confiable. Fallará con los archivos con nombre impar enumerados arriba. Se ahogará con varios nombres. Tienes que borrar uno por uno hasta que encuentres a los que tienen problemas.

2.- ls

El GNU ls aceptará el "final de las opciones" (--) llave.

ls -d ./*/                     ### more reliable BSD ls
ls -d -- */                    ### more reliable GNU ls

3.-printf

Para enumerar cada directorio en su propia línea (en una columna, similar a ls -1), use:

$ printf "%s\n" */        ### Correct even with "-", spaces or newlines.

Y, aún mejor, podríamos eliminar el final /:

$ set -- */; printf "%s\n" "${@%/}"        ### Correct with spaces and newlines.

Un intento como este:

$ for i in $(ls -d */); do echo ${i%%/}; done

Fallará en:

  • algunos nombres (ls -d */) como ya se mostró arriba.
  • se verá afectado por el valor de IFS.
  • dividirá nombres en espacios y pestañas (con valores predeterminados) IFS)
  • cada nueva línea en el nombre iniciará un nuevo comando de eco.

4.- Función

Finalmente, el uso de la lista de argumentos dentro de una función no afectará a la lista de argumentos del shell en ejecución actual. Simplemente:

$ listdirs(){ set -- */; printf "%s\n" "${@%/}"; }
$ listdirs

presenta esta lista:

--
-
*
cs
dir with spaces
draft
files
-h
masters
-n
static
-v var

Estas opciones son seguras con varios tipos de nombres de archivo impares.


28
2017-07-24 06:02



los tree comando también es bastante útil aquí. De forma predeterminada, mostrará todos los archivos y directorios a una profundidad completa, con algunos caracteres ascii que muestran el árbol de directorios.

$ tree
.
├── config.dat
├── data
│   ├── data1.bin
│   ├── data2.inf
│   └── sql
|   │   └── data3.sql
├── images
│   ├── background.jpg
│   ├── icon.gif
│   └── logo.jpg
├── program.exe
└── readme.txt

Pero si quisiéramos obtener solo los directorios, sin el árbol ascii, y con la ruta completa desde el directorio actual, podría hacer:

$ tree -dfi
.
./data
./data/sql
./images

Los argumentos son:

-d     List directories only.
-f     Prints the full path prefix for each file.
-i     Makes tree not print the indentation lines, useful when used in conjunction with the -f option.

Y si luego quiere la ruta absoluta, puede comenzar especificando la ruta completa al directorio actual:

$ tree -dfi "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/data/sql
/home/alice/Documents/images

Y para limitar el número de subdirectorios, puede establecer el nivel máximo de subdirectorios con -L level, p.ej:

$ tree -dfi -L 1 "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/images

Se pueden ver más argumentos con árbol de hombre


13
2018-06-16 15:30



En caso de que se pregunte por qué la salida de 'ls -d * /' le da dos rachas al final, como:

[prompt]$ ls -d */    
app//  cgi-bin//  lib//        pub//

es probable que se deba a que en algún lugar los archivos de configuración de su shell o sesión alias tienen el comando ls en una versión de ls que incluye el distintivo -F. Esa bandera agrega un carácter a cada nombre de salida (que no es un archivo simple) que indica el tipo de cosa que es. De modo que una barra oblicua es la que coincide con el patrón '* /', y la otra barra inclinada es el indicador de tipo adjunto.

Para deshacerte de este problema, por supuesto podrías definir un alias diferente para ls. Sin embargo, para no invocar temporalmente el alias, puede anteponer el comando con la barra diagonal inversa:

\ ls -d * /


11
2017-10-28 23:05



Solo agrego esto a mi .bashrc archivo (también puede simplemente escribirlo en la línea de comando si solo lo necesita / desea para una sesión)

alias lsd='ls -ld */'

entonces lsd producirá el resultado deseado.


9
2018-06-02 23:02



Si el directorio oculto no es necesario para ser enumerado, ofrezco:

ls -l | grep "^d" | awk -F" " '{print $9}'  

Y si se necesitan directorios ocultos para ser enumerados, use:

ls -Al | grep "^d" | awk -F" " '{print $9}'

O

find -maxdepth 1 -type d | awk -F"./" '{print $2}'

7
2017-08-29 10:21