it-swarm-es.tech

¿Cómo cuento todos los archivos de forma recursiva a través de directorios?

Quiero ver cuántos archivos hay en subdirectorios para saber dónde está todo el uso de inodo en el sistema. Algo así como lo haría para el uso del espacio

du -sh /*

lo que me dará el espacio utilizado en los directorios fuera de la raíz, pero en este caso quiero la cantidad de archivos, no el tamaño.

52
xenoterracide
find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

Gracias a Gilles y xenoterracide por las soluciones de seguridad/compatibilidad.

La primera parte: find -maxdepth 1 -type d devolverá una lista de todos los directorios en el directorio de trabajo actual. Esto se canaliza a ...

La segunda parte: while read -r dir; do comienza un ciclo while, siempre que la tubería que entra en while esté abierta (que es hasta que se envíe la lista completa de directorios), el comando de lectura colocará la siguiente línea en la variable "dir". Entonces continúa ...

La tercera parte: printf "%s:\t" "$dir"; imprimirá la cadena en "$ dir" (que contiene uno de los nombres de directorio) seguido de una pestaña.

La cuarta parte: find "$dir -f file" hace una lista de todos los archivos dentro del nombre del directorio contenido en "$ dir". Esta lista se envía a ...

La quinta parte: wc -l; cuenta el número de líneas que se envían a su entrada estándar.

La parte final: done simplemente finaliza el ciclo while.

Entonces obtenemos una lista de todos los directorios en el directorio actual. Para cada uno de esos directorios, generamos una lista de todos los archivos en él para que podamos contarlos todos usando wc -l. El resultado se verá así:

./dir1: 234
./dir2: 11
./dir3: 2199
...
67
Shawn J. Goff

Tratar find . -type f | wc -l, contará todos los archivos en el directorio actual, así como todos los archivos en subdirectorios. Tenga en cuenta que todos los directorios no se contarán como archivos, solo los archivos normales sí.

17
herohuyongtao

Aquí hay una compilación de algunos comandos útiles de listado (re-hash basado en el código de usuarios anteriores):

Lista de carpetas con conteo de archivos:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); printf "%4d : %s\n" $n "$dir"; done

Lista de carpetas con un recuento de archivos distinto de cero:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Lista de carpetas con recuento de subcarpetas:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; printf "%4d : %s\n" $n "$dir"; done

Lista de carpetas con recuento de subcarpetas distinto de cero:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Lista de carpetas vacías:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -eq 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Lista de carpetas no vacías con conteo de contenido:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done
13
DolphinDream

Tratar:

find /path/to/start/at -type f -print | wc -l

como punto de partida, o si realmente solo desea recurrir a través de los subdirectorios de un directorio (y omitir los archivos en ese directorio de nivel superior)

find `find /path/to/start/at -mindepth 1 -maxdepth 1 -type d -print` -type f -print | wc -l
12
Cry Havok

La siguiente solución cuenta el número real de inodos usados ​​a partir del directorio actual:

find . -print0 | xargs -0 -n 1 ls -id | cut -d' ' -f1 | sort -u | wc -l

Para obtener el número de archivos del mismo subconjunto, use:

find . | wc -l

Para soluciones que exploran solo subdirectorios, sin tener en cuenta los archivos en el directorio actual, puede consultar otras respuestas.

4
mouviciel

OS X 10.6 se ahoga con el comando en la respuesta aceptada, porque no especifica una ruta para find. En su lugar use:

find . -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
2
abeboparebop

Sé que llego tarde a la fiesta, pero creo que esta solución pura bash (u otra Shell que acepta doble estrella glob) podría ser mucho más rápida en algunas situaciones:

shopt -s globstar    # to enable ** glob in bash
for dir in */; do a=( "$dir"/**/* ); printf "%s\t%s\n" "$dir:" "${#a[*]}"; done

salida:

d1/:    302
d2/:    24
d3/:    640
...
2
jimmij

Prueba esto:

find -type d -print0 | xargs -0 -I {} sh -c 'printf "%s\t%s\n" "$(find "{}" -maxdepth 1 -type f | wc -l)" "{}"'

Debería funcionar bien a menos que los nombres de archivo incluyan nuevas líneas.

du --inodes

No estoy seguro de por qué nadie (incluido yo mismo) sabía:

du --inodes
--inodes
      list inode usage information instead of block usage

Estoy bastante seguro de que esto resuelve el problema del OP. He comenzado a usarlo mucho para descubrir dónde está toda la basura en mis enormes unidades (y descargarla en un disco más antiguo).

Informacion adicional

Si NO desea recurrir (que puede ser útil en otras situaciones), agregue

-S, --separate-dirs
1
Sridhar Sarnobat

Si tiene instalado ncdu (algo imprescindible cuando desea realizar una limpieza), simplemente escriba c para "Activar o desactivar la visualización de recuentos de elementos secundarios". Y C para "Ordenar por elementos".

1
Demi-Lune