Soy capaz de enumerar todos los directorios por

find ./ -type d

He tratado de mostrar el contenido de cada directorio y contar el número de archivos en cada directorio mediante el comando siguiente

find ./ -type d | xargs ls -l | wc -l

Pero esto resume el número total de líneas devuelto por

find ./ -type d | xargs ls -l

Hay una manera que puedo contar el número de archivos en cada directorio?

  • Estás buscando una manera de contar el número de archivos en cada uno de los sub-directorios directamente bajo ./ ?
  • ¿Cómo es un off-topic pregunta?? Me gustaría ver de cerca a los votantes comentarios con razón! Si esto es off-topic, a continuación, no te pertenece? super usuario? No lo creo..
  • shell-script, por lotes de comandos están bajo el ámbito de la programación!
  • Yo estaba a punto de correo Python solución entonces me di cuenta de que la pregunta es cerrada.
  • votó a favor de volver a abrirlo. Puede haber otras respuestas que podría ser útil en muchas situaciones (incluyendo la programación de script, que es la razón por la que llegó a esta pregunta).
  • No entiendo el off-topic votar, a menos que sea porque de alguna manera shell scripting no cuenta? El «Off Topic» votos parecer un poco agresivo en la Pila de sitios a veces.

InformationsquelleAutor user784637 | 2013-03-05

15 Comentarios

  1. 88

    Suponiendo que tiene GNU encontrar, vamos a encontrar los directorios y dejar bash hacer el resto:

    find . -type d -print0 | while read -d '' -r dir; do
        files=("$dir"/*)
        printf "%5d files in directory %s\n" "${#files[@]}" "$dir"
    done
    • Solo es un poco diferente de la versión de la anterior, de modo que: ( sugerencia: su ordenadas por nombre, y en el csv) para x en find . -maxdepth 1 -type d | sort; hacer y=find $x | wc -l; echo $x,$y; hecho
    • Que no va a funcionar si cualquier nombre de archivo contiene espacios.
    • El más grande! Ponerlo en una sola línea (por lo que es cómodo para el uso directo en shell): find . -type d -print0 | while read -d '' -r dir; do files=("$dir"/*); printf "%5d files in directory %s\n" "${#files[@]}" "$dir"; done
    • Yo necesitaba para obtener el número de todos los archivos (de forma recursiva recuento) en cada subdirectorio. Esta modificación le da a usted que: find . -maxdepth 1 -type d -print0 | while read -d '' -r dir; do num=$(find $dir -ls | wc -l); printf "%5d files in directory %s\n" "$num" "$dir"; done
    • Supongo que esto es sin contar los llamados .hidden archivos.
    • Exactamente lo que necesitaba, gracias @Omid manera Fácil de ordenar los resultados?
    • El siguiente va a hacer: find . -maxdepth 1 -type d -print0 | while read -d '' -r dir; do num=$(find "$dir" -ls | wc -l); printf "%5d files in directory %s\n" "$num" "$dir"; done | sort -rn -k1
    • No puede corregirlo, pero se bloquea para los directorios vacíos a la derecha ?
    • muchos bash aplicación tiene un error de bucle de iteraciones. Por ejemplo, si va a escanear extremally gran sistema de ficheros con más de 10 millones de archivos, entonces es posible almacenar muchos objetos temporales dentro de bash intérprete. esta causa, el bucle es más lento, paso a paso, y, finalmente, será visible como congelados proces. por lo general, no es buena idea usar bash para el bucle.

  2. 128

    Se imprime el número de archivos por directorio el directorio actual nivel:

    du -a | cut -d/ -f2 | sort | uniq -c | sort -nr
    • Por lejos el mejor (y más elegante) solución si uno quiere una lista con el número de archivos en la parte superior del nivel de directorios de forma recursiva.
    • Esto tiene dos problemas: Se cuenta con un archivo por cada directorio más de lo que realmente hay, y da un inútil línea que contiene el tamaño del directorio actual como «1 tamaño«. Ambos pueden ser fijados con du -a | sed '/.*\.\/.*\/.*/!d' | cut -d/ -f2 | sort | uniq -c. Agregar | sort -nr para ordenar por el número en lugar del nombre del directorio.
    • Me gustaría señalar que esto funciona en OSX, demasiado. (Sólo copiar-pegar Linux asesoramiento en un OSX shell generalmente no funciona.)
    • recupera innecesarios tamaño du -un . La mejor manera es usando el comando buscar. pero la idea principal es exactamente el mismo 🙂
    • Este es uno para correr muy lento para mí
    • encontrar . -tipo f | cut-d/ -f2 | sort | uniq -c | sort-nr # corrige los problemas mencionados por el postre

  3. 13

    Podría organizar para encontrar todos los archivos, retire los nombres de archivo, dejando una línea que contiene el nombre de directorio para cada archivo, y luego contar el número de veces que cada directorio aparece:

    find . -type f |
    sed 's%/[^/]*$%%' |
    sort |
    uniq -c

    El único problema de esto es que si usted tiene alguna nombres de archivo o de directorio de nombres que contiene un carácter de nueva línea, la cual es bastante raro. Si usted realmente tiene que preocuparse acerca de las nuevas líneas en los nombres de archivo o de directorio de nombres, le sugiero que encontrarlos y corregirlos para que no contiene saltos de línea (y en silencio persuadir a la parte culpable del error de sus caminos).


    Si usted está interesado en el recuento de los archivos en cada uno de los sub-directorios del directorio actual, contando todos los archivos en todos los sub-directorios junto con los archivos en la inmediata sub-directorio, luego me iba a adaptar el sed comando para imprimir sólo el directorio de nivel superior:

    find . -type f |
    sed -e 's%^\(\./[^/]*/\).*$%%' -e 's%^\.\/[^/]*$%./%' |
    sort |
    uniq -c

    El primer patrón de captura el inicio del nombre, el punto, la barra, el nombre de la siguiente barra y la barra, y sustituye a la línea con sólo la primera parte, así:

    ./dir1/dir2/file1

    es reemplazado por

    ./dir1/

    La segunda reemplazar la captura directamente los archivos en el directorio actual; no tienen una barra al final, y los que se reemplace por ./. La ordenación y recuento de entonces trabaja en el número de los nombres.

    • Esto no salida de los nombres de directorio que no contienen archivos. No estoy seguro si esto es necesario.
    • Cierto, no lo hace. ‘Tis no particularmente trivial solucionarlo para ello, desde el directorio vacío nombres no se garantiza incluso a aparecer en la salida de find. Algunos podrían: si hay un archivo dir1/dir2/dir3/file1, pero dir1/dir2 contiene sólo los sub-directorios (no llanura de archivos), entonces usted puede deducir su presencia. Pero si dir1/dir4 no tiene archivos, nombre, simplemente no aparece.
    • Muy respuesta útil si sólo desea ver los subdirectorios del directorio actual.
    • Sólo se detuvo para decir gracias. 3 años después de que esto fue publicado, yo estaba buscando para el recuento de nivel 2 carpetas por carpeta. Tu post me ha salvado potencialmente muchas horas de retoques con sed, encontrar y quién sabe qué más
  4. 11

    Aquí es una manera de hacerlo, pero probablemente no el más eficiente.

    find -type d -print0 | xargs -0 -n1 bash -c 'echo -n "$1:"; ls -1 "$1" | wc -l' --

    Da una salida como esta, con el nombre de directorio, seguido por el conde de entradas en el directorio. Tenga en cuenta que la salida de recuento se incluyen también las entradas de directorio que puede no ser lo que usted desea.

    ./c/fa/l:0
    ./a:4
    ./a/c:0
    ./a/a:1
    ./a/a/b:0
    • Me parece muy caro para ejecutar 3 comandos (bash, ls, wc) para cada directorio que se encuentra por find.
    • De acuerdo, por tanto, la primera línea de mi respuesta. Su solución es la mejor.
    • genial esto es lo que estoy buscando se puede saber qué es el ‘–‘ al final?
    • El — pertenece a la orden de bash que se generó por xargs. De man bash, A -- signals the end of options and disables further option processing. En este caso es evitar un mal llamado archivo que se encuentra como parte de la búsqueda de convertirse en parte del argumento de procesamiento para bash.
    • upvoted de una línea de solución
  5. 7

    Todos los demás, la solución tiene el inconveniente o la otra.

    find -type d -readable -exec sh -c 'printf "%s " "$1"; ls -1UA "$1" | wc -l' sh {} ';'

    Explicación:

    • -type d: estamos interesados en directorios.
    • -readable: Solo queremos que ellos si es posible a la lista de los archivos en ellos. Tenga en cuenta que find todavía emiten un error cuando se intenta buscar más directorios en ellos, pero esto impide llamar a -exec para ellos.
    • -exec sh -c BLAH sh {} ';': para cada directorio, ejecute este fragmento de secuencia, con $0 conjunto para sh y $1 establecer el nombre del archivo.
    • printf "%s " "$1": portabilidad, y mínimamente imprimir el nombre del directorio, seguido por un espacio, no un salto de línea.
    • ls -1UA: lista los archivos, uno por línea, en el directorio de la orden (para evitar la pérdida de la tubería), excluyendo sólo los directorios especiales . y ..
    • wc -l: recuento de las líneas
    • Modificación para mostrar el archivo cuenta primero en la línea, y para ordenar por ellos: find -type d -readable -exec sh -c 'ls -1UA "$1" | wc -l | tr -d "\n" ; printf "\t%s\n" "$1" ' sh {} ';' | sort -n
    • se ejecuta el shell muchas veces, entonces es lento y altamente utiliza los recursos.
    • Este es el único comando que trabajó para mí. Gracias!
  6. 6
    find . -type f | cut -d/ -f2 | sort | uniq -c
    • find. -type f para buscar todos los elementos del tipo de archivo
    • cut -d/-f2 para cortar su carpeta específica
    • sort para ordenar la lista de foldernames
    • uniq -c para devolver el número de veces que cada nombre de carpeta que se ha contado
    • Esto es mucho mejor que el aceptado la respuesta, pues se obtiene un resumen de los directorios de alto nivel!
  7. 4

    Esto también se puede hacer con un bucle por ls en lugar de encontrar

    for f in */; do echo "$f -> $(ls $f | wc -l)"; done

    Explicación:

    for f in */; de bucle a través de todos los directorios

    do echo "$f -> – imprimir cada nombre de directorio

    $(ls $f | wc -l) llamada ls para este directorio y el conteo de líneas de

    • Esto no funciona correctamente si los nombres de directorios que contienen espacios en blanco.
    • o si hay mucho de los archivos…
  8. 3

    Versión ligeramente modificada de Sebastián respuesta usando find en lugar de du (para excluir tamaño de archivo relacionados con la sobrecarga que du tiene que realizar y que nunca se usa):

     find ./ -mindepth 2 -type f | cut -d/ -f2 | sort | uniq -c | sort -nr

    -mindepth 2 parámetro se utiliza para excluir los archivos en el directorio actual. Si se quita, vas a ver un montón de líneas como las siguientes:

      234 dir1
      123 dir2
        1 file1
        1 file2
        1 file3
          ...
        1 fileN

    (como en el duvariante basada en no)

    Si usted no necesita contar los archivos en el directorio actual, así, el uso de esta versión mejorada:

    { find ./ -mindepth 2 -type f | cut -d/ -f2 | sort && find ./ -maxdepth 1 -type f | cut -d/ -f1; } | uniq -c | sort -nr

    La salida será similar a la siguiente:

      234 dir1
      123 dir2
       42 .
  9. 2

    Esto debe devolver el nombre del directorio, seguido por el número de archivos en el directorio.

    findfiles() {
        echo "$1" $(find "$1" -maxdepth 1 -type f | wc -l)
    }
    
    export -f findfiles
    
    find ./ -type d -exec bash -c 'findfiles "$0"' {} \;

    Ejemplo de salida:

    ./ 6
    ./foo 1
    ./foo/bar 2
    ./foo/bar/bazzz 0
    ./foo/bar/baz 4
    ./src 4

    La export -f es necesario porque el -exec argumento de find no permite la ejecución de una función bash a menos que se invoca bash de forma explícita, y que necesita para exportar la función definida en el ámbito actual a la nueva shell de forma explícita.

    • Esto parece demasiado complicado. También a mí me parece que da acumulativa cuenta de una jerarquía de directorios, tales como ./dir1/dir2/dir3 (contando los archivos en dir1 y sus subdirectorios todos juntos, en lugar de contar los archivos en dir1/dir2/dir3 por separado de aquellos en dir1/dir2 y por separado de aquellos en /dir1).
    • Entendí que era lo que el autor quería. Si ese no fuera el caso, entonces estoy de acuerdo en que la respuesta no es pertinente a la cuestión.
    • Bien, la lectura de la pregunta, una vez más, me di cuenta de que tienes razón – han modificado la respuesta en consecuencia.
  10. 1

    encontrar . -tipo f -printf ‘%h\n’ | sort | uniq -c

    da por ejemplo:

      5 .
      4 ./aln
      5 ./aln/iq
      4 ./bs
      4 ./ft
      6 ./hot
  11. 1

    He combinado @glenn jackman respuesta y @pcarvalho la respuesta(en la lista de comentarios, hay algo mal con pcarvalho de la respuesta debido a que el extra de estilo de la función de control de carácter ‘`‘(acento grave)).

    Mi script puede aceptar camino como un augument y ordenar la lista del directorio, como ls -l, también puede controla el problema del «espacio» en el nombre de archivo».

    #!/bin/bash
    OLD_IFS="$IFS"
    IFS=$'\n'
    for dir in $(find $1 -maxdepth 1 -type d | sort); 
    do
        files=("$dir"/*)
        printf "%5d,%s\n" "${#files[@]}" "$dir"
    done
    FS="$OLD_IFS"

    Mi primera respuesta en stackoverflow, y espero que pueda ayuda ^_^

  12. 0

    He intentado con algunos de los otros aquí, pero terminó con subcarpetas incluidas en el archivo de la cuenta cuando yo sólo quería los archivos. Esto imprime ./folder/path<tab>nnn con el número de archivos, no incluidas las subcarpetas, para cada subcarpeta de la carpeta actual.

    for d in `find . -type d -print` 
    do 
      echo -e "$d\t$(find $d -maxdepth 1 -type f -print | wc -l)"
    done
  13. 0

    Manera fácil de forma recursiva buscar archivos de un tipo determinado. En este caso, .jpg archivos de todas las carpetas en el directorio actual:

    find . -name *.jpg -print | wc -l

  14. 0

    Una super rápido milagro de comando, que de forma recursiva atraviesa archivos para contar el número de imágenes en un directorio y organizar la salida por la extensión de la imagen:

    find . -type f | sed -e 's/.*\.//' | sort | uniq -c | sort -n | grep -Ei '(tiff|bmp|jpeg|jpg|png|gif)$'

    Créditos: https://unix.stackexchange.com/a/386135/354980

  15. -1

    Esto le dará el recuento general.

    for file in */; do echo "$file -> $(ls $file | wc -l)"; done | cut -d ' ' -f 3| py --ji -l 'numpy.sum(l)'
    • Nada de lo que no. Se considerará solamente un nivel de subdirectorios.
    • Sí @Kusalananda, funciona para un solo nivel.

Dejar respuesta

Please enter your comment!
Please enter your name here