contando el número de directorios en un directorio específico

103

Cómo contar el número de carpetas en un directorio específico. Estoy usando el siguiente comando, pero siempre proporciona uno adicional.

find /directory/ -maxdepth 1 -type d -print| wc -l

Por ejemplo, si tengo 3 carpetas, este comando proporciona 4. Si contiene 5 carpetas, el comando proporciona 6. ¿Por qué?

usuario2566898
fuente
4
El conteo adicional de 1 se debe al directorio actual '.' , que también se tiene en cuenta mediante 'buscar'.
patel deven

Respuestas:

94

find también está imprimiendo el directorio en sí:

$ find .vim/ -maxdepth 1 -type d
.vim/
.vim/indent
.vim/colors
.vim/doc
.vim/after
.vim/autoload
.vim/compiler
.vim/plugin
.vim/syntax
.vim/ftplugin
.vim/bundle
.vim/ftdetect

En su lugar, puede probar los elementos secundarios del directorio y no descender a ellos en absoluto:

$ find .vim/* -maxdepth 0 -type d
.vim/after
.vim/autoload
.vim/bundle
.vim/colors
.vim/compiler
.vim/doc
.vim/ftdetect
.vim/ftplugin
.vim/indent
.vim/plugin
.vim/syntax

$ find .vim/* -maxdepth 0 -type d | wc -l
11
$ find .vim/ -maxdepth 1 -type d | wc -l
12

También puede utilizar ls:

$ ls -l .vim | grep -c ^d
11


$ ls -l .vim
total 52
drwxrwxr-x  3 anossovp anossovp 4096 Aug 29  2012 after
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 autoload
drwxrwxr-x 13 anossovp anossovp 4096 Aug 29  2012 bundle
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 colors
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 compiler
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 doc
-rw-rw-r--  1 anossovp anossovp   48 Aug 29  2012 filetype.vim
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftdetect
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftplugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 indent
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 plugin
-rw-rw-r--  1 anossovp anossovp 2505 Aug 29  2012 README.rst
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 syntax

$ ls -l .vim | grep ^d
drwxrwxr-x  3 anossovp anossovp 4096 Aug 29  2012 after
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 autoload
drwxrwxr-x 13 anossovp anossovp 4096 Aug 29  2012 bundle
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 colors
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 compiler
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 doc
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftdetect
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftplugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 indent
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 plugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 syntax
Pavel Anossov
fuente
¡Agradable! ¿Cómo harías esto $ ls -l .vimcon PHP? O cómo obtener solo el total, sin la lista. Quiero decir, en este caso obtener solo 52?
Pathros
Ja. Me encanta cómo el argumento contra PowerShell es que BASH es más fácil en todos los sentidos ... ¿quieres ver el comando POSH para hacer esto? (ls).Count
Cañón de Kolob
@Pathros Usa glob con el indicador GLOB_ONLYDIR y cuenta () el resultado.
Pilipe
1
ls -l | grep -c ^des completamente simple y funciona. @Pathros probablemente haya una forma mejor en PHP, pero en el peor de los casos en PHP, siempre puede usar la función shell_exec () para ejecutar la línea de comando y devolver los resultados a una cadena. ie $dirCount = shell_exec('ls -l | grep -c ^d');
gigabyte
66

Obtenga un recuento de solo los directorios en el directorio actual

echo */ | wc

saldrás puesto como 1 309 4594

2nd digitrepresenta no. de directorios.

o

tree -L 1 | tail -1

EmptyData
fuente
8
Esto falla si hay espacios en los nombres de directorio, desafortunadamente.
Michael Campbell
zsh: no matches found: */necesita nullglob
Anne van Rossum
@AnnevanRossum ¿Tienes echo. typewhich echo
EmptyData
7
El primero se puede mejorar un poco más:echo */ | wc -w
ibic
Tenga en cuenta que esto contará 1 si no hay directorios en lugar de 0.
jinawee
27
find . -mindepth 1 -maxdepth 1 -type d | wc -l

Para buscar -mindepthsignifica el número total recusivo en directorios

-maxdepth significa número total recusivo en directorios

-type d significa directorio

Y para los wc -lmedios contar las líneas de la entrada

shiyani suresh
fuente
2
¿Puede explicar su respuesta por favor (dentro de su respuesta)?
Zulu
-mindepth significa número total recusivo en directorios, -maxdepth significa número total recusivo en directorios, -type d significa directorio y wc -l significa recuento de líneas de la lista de directorios dada
shiyani suresh
find . -mindepth 1 -maxdepth 1 -type d | wc -lle dará muchos espacios entre el número, por ejemplo: `2` puede evitarlo usando esto: dir_count=`find . -maxdepth 1 -type d | wc -l | xargs`; echo $dir_count # will print just 2 y podría ser útil para condiciones, como:if (( $dir_count > 1 )); then echo "Yaa"; fi # will print "Yaa"
naorz
16

Si solo tiene directorios en la carpeta y no hay archivos, esto lo hace:

ls | wc -l
Brainmaniac
fuente
2
Esto también obtiene archivos, pero la pregunta era sobre carpetas / directorios.
Robert
12

La mejor manera de navegar a su unidad y simplemente ejecutar

ls -lR | grep ^d | wc -l

y buscar todas las carpetas en total, incluidos los subdirectorios?

find /mount/point -type d | wc -l

... o encontrar todas las carpetas en el directorio raíz (sin incluir los subdirectorios)?

find /mount/point -maxdepth 1 -type d | wc -l

¡Salud!

Manish Shrivastava
fuente
Tenga en cuenta que los ls anteriores -lRignoran el directorio con prefijo de punto mientras los find -type d cuenta, por lo que el recuento dado por el primer comando es incorrecto si tiene directorios con prefijo de punto (por ejemplo, tiene el subdirectorio .git). Simplemente no se puede utilizar -lRaporque se llega también para cada directorio .y ..entrada. Se aplica también a la respuesta de @Pavel Anossov
marcz
12

Ejecute stat -c %h foldery reste 2 del resultado. Esto emplea un solo subproceso en lugar de los 2 (o incluso 3) requeridos por la mayoría de las otras soluciones aquí (típicamente findmás wc).

Usando sh / bash:

cnt = $ ((`stat -c% h folder` - 2))
echo $ cnt # 'echo' es un sh / bash incorporado, no un proceso adicional

Usando csh / tcsh:

@ cnt = `stat -c% h folder` - 2
echo $ cnt # 'echo' es un csh / tcsh incorporado, no un proceso adicional


Explicación: stat -c %h folderimprime el número de enlaces físicos a la carpeta , y cada subcarpeta de la carpeta contiene una entrada ../ que es un enlace fijo a la carpeta . Debe restar 2 porque hay dos enlaces duros adicionales en el recuento:

  1. la propia entrada ./ autorreferencial de la carpeta , y
  2. carpeta de enlace de los padres 's de la carpeta
textral
fuente
Relacionado con esta pregunta: [¿Por qué un directorio nuevo tiene un recuento de enlaces físicos de 2 antes de que se le agregue algo? ] ( unix.stackexchange.com/questions/101515 ) Explica por qué esta es una excelente respuesta. Desafortunadamente, ¡esto no recibió suficiente atención! Si bien es una buena respuesta, el resultado depende desafortunadamente del sistema de archivos, pero para la mayoría de los sistemas de archivos comunes, esto funcionará.
kvantour
8

Creo que lo mas facil es

  ls -ld images/* | wc -l

¿Dónde imagesestá su directorio de destino? El indicador -d limita a los directorios, y el indicador -l realizará un listado por línea, compatible con el muy conocido wc -lpara el recuento de líneas.

Briceburg
fuente
También devuelve el resultado +1
josef
1
De acuerdo con man ls, -dhace: "enumera los directorios en sí, no su contenido", es decir, si ejecuta ls /tmp, obtendrá lo que hay /tmp, y si lo ejecuta ls -d /tmp, simplemente obtendrá /tmp. El -dconmutador no filtra directorios, como se solicitó.
Robert
5

Algunos ejemplos útiles:

contar archivos en el directorio actual

/bin/ls -lA  | egrep -c '^-'

contar directorios en el directorio actual

/bin/ls -lA  | egrep -c '^d'

contar archivos y directorios en el directorio actual

/bin/ls -lA  | egrep -c '^-|^d'

contar archivos y directorios en un subdirectorio

/bin/ls -lA  subdir_name/ | egrep -c '^-|^d'

He notado algo extraño (al menos en mi caso):

Cuando he tratado con lsen lugar /bin/ls del -Aparámetro do not list implied . and ..no funciona como pensábamos. Cuando uso lsese programa ./ y ../ Entonces, el resultado es un recuento incorrecto. SOLUCIÓN: en /bin/lscambiols

MTK
fuente
4

No de directorio que podemos encontrar usando el siguiente comando

ls -l | grep "^d" | wc -l

usuario1388547
fuente
Solo ls -l | grep ^d | wc -lservirá, no es necesario usarlo "aquí
kaspiotr
3

Una solución de bash pura:

shopt -s nullglob
dirs=( /path/to/directory/*/ )
echo "There are ${#dirs[@]} (non-hidden) directories"

Si también desea contar los directorios ocultos:

shopt -s nullglob dotglob
dirs=( /path/to/directory/*/ )
echo "There are ${#dirs[@]} directories (including hidden ones)"

Tenga en cuenta que esto también contará los enlaces a directorios. Si no quieres eso, es un poco más difícil con este método.


Usando find:

find /path/to/directory -type d \! -name . -prune -exec printf x \; | wc -c

El truco consiste en generar una salida xestándar cada vez que se encuentra un directorio, y luego usarlo wcpara contar el número de caracteres. Esto contará el número de todos los directorios (incluidos los ocultos), excluidos los enlaces.


Los métodos presentados aquí son seguros para los personajes divertidos que pueden aparecer en los nombres de los archivos (espacios, nuevas líneas, caracteres globales, etc.).

gniourf_gniourf
fuente
¡Esta es la mejor solución presentada en esta pregunta y funcionará siempre!
kvantour
3

Usando zsh:

a=(*(/N)); echo ${#a}

El Nes un nullglob, /hace que se acople directorios, #los recuentos. Manejará perfectamente los espacios en los nombres de los directorios y también regresará 0si no hay directorios.

Anne van Rossum
fuente
0

Cuente todos los archivos y subcarpetas, estilo Windows:

dir=/YOUR/PATH;f=$(find $dir -type f | wc -l); d=$(find $dir -mindepth 1 -type d | wc -l); echo "$f Files, $d Folders"
margenn
fuente
0

Si desea utilizar expresiones regulares, intente:

ls -c | grep "^d" | wc -l
makassi
fuente
1
¿Le gustaría agregar alguna explicación a su respuesta de solo código? Ayudaría a combatir la idea errónea de que StackOverflow es un servicio gratuito de escritura de código. Además, eche un vistazo aquí para mejorar la apariencia: stackoverflow.com/editing-help
Yunnosch
0

La mejor respuesta a lo que quieres es

echo `find . -maxdepth 1 -type d | wc -l`-1 | bc

esto resta uno para eliminar el '.' no deseado directorio que encuentra listas (como patel deven mencionado anteriormente).

Si desea contar las subcarpetas de forma recursiva, deje la opción maxdepth, por lo que

echo `find . -type d | wc -l`-1 | bc

PD: Si encuentra fea la sustitución de comandos, restar uno se puede hacer como un flujo puro usando sedy bc.

Restando uno del recuento:

find . -maxdepth 1 -type d | wc -l | sed 's/$/-1\n/' | bc

o, agregando conteo a menos uno:

find . -maxdepth 1 -type d | wc -l | sed 's/^/-1+/' | bc
Dr. Persona Persona II
fuente
-1

La mejor manera de hacerlo:

ls -la | grep -v total | wc -l

Esto le da el recuento perfecto.

Manoj
fuente
6
¡Quieres decir que esa es la peor forma de hacerlo! además, esto no cuenta el número de directorios. ¿Y si hay un nombre de directorio que contiene la cadena total? tu método está roto :(. ¡No analicels !
gniourf_gniourf