¿Puedo determinar el número de subdirectorios en un directorio usando `ls -l`?


8

Cuando se muestran directorios usando ls -l, su número de enlaces (el segundo campo en la salida) es al menos dos: uno para el nombre del directorio y otro para.

$ mkdir foo
$ ls -l
total 2
drwxr-xr-x  2 user   wheel  512  4 oct 14:02 foo

¿Es seguro asumir siempre que el número de enlaces por encima de 2 corresponde al número de subdirectorios en este directorio ( ..enlaces)?

Respuestas:


7

Por lo general, es cierto en sistemas Unix que el número de enlaces a un directorio es el número de subdirectorios más 2. Sin embargo, hay casos en los que esto no es cierto:

  • Algunas unidades permiten enlaces duros a directorios. Luego habrá más de 2 enlaces que no corresponden a subdirectorios.

  • Hay sistemas de archivos donde los directorios no tienen entradas para .y ... El manual de búsqueda de GNU menciona algunos ejemplos en la discusión de su -noleafopción (que deshabilita una optimización que asume eso .y ..existe en todos los directorios): "CD-ROM o sistemas de archivos MS-DOS o puntos de montaje de volumen AFS"

Una forma casi confiable de contar el número de subdirectorios (aún puede fallar si un nombre de archivo contiene un carácter de nueva línea) es

$(($(LC_ALL=C ls -la /path/to/directory | grep '^d' | wc -l) - 2)

Una forma más confiable utiliza globos de concha */y .*/; como de costumbre, manejar el caso donde el patrón no coincide es un poco molesto (excepto en bash y zsh donde puede activar la nullglobopción).


2

Aquí hay otra forma de contar subdirectorios (no recursivamente) en Bash:

(
shopt -s nullglob dotglob
printf '%s\000' */ | tr -dc '\0' | wc -c  # wc counts null bytes
)

Debido a que cada nombre de archivo está siendo terminado por un carácter ASCII NUL, esto debería funcionar correctamente incluso si un nombre de archivo contiene un carácter de nueva línea.



1

No puedo encontrar nada en la documentación que confirme que el número de enlaces siempre será +2 en el número de subdirectorios.

Pero, para encontrar la cantidad correcta, use:

find . -type d -mindepth 1  -maxdepth 1 | wc -l

O si tiene que usar ls -l, vea la otra respuesta.


Creo que quisiste decir -type d, pero: 1. esto requiere GNU find; 2. necesita restar 1 para el directorio de inicio (o pasar -mindepth 1).
Gilles 'SO- deja de ser malvado'

0

No lo uses lspara esto . Aquí hay una forma que funciona con todos los nombres de archivo, incluso aquellos que contienen líneas nuevas, porque imprime solo un carácter de línea nueva en lugar del nombre de archivo:

find . -mindepth 1 -maxdepth 1 -type d -printf '\n' | wc -l

Editar: La versión actual no da lugar a ninguna advertencia, debido -mindepthy -maxdepthdebe ser antes -type(el árbol de directorios se poda antes de comprobar si los directorios, para ahorrar tiempo).

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.