¿Cómo puedo obtener un recuento de archivos en un directorio usando la línea de comando?


Respuestas:


240

Usando una definición amplia de "archivo"

ls | wc -l

(tenga en cuenta que no cuenta los archivos ocultos y supone que los nombres de los archivos no contienen caracteres de nueva línea).

Para incluir archivos ocultos (excepto .y ..) y evitar problemas con los caracteres de nueva línea, la forma canónica es:

find . ! -name . -prune -print | grep -c /

O recursivamente:

find .//. ! -name . -print | grep -c //

23
wces un programa de "conteo de palabras". El -lcambio hace que cuente líneas. En este caso, cuenta las líneas en la salida de ls. Esta es siempre la forma en que me enseñaron a obtener un recuento de archivos para un directorio determinado, también.
Sandy

20
añada por favor nota que lslo hace ls -1si la salida es una pipa.
lesmana

66
eso no incluye todo en un directorio: ha perdido archivos de puntos y también recopila un par de líneas adicionales. Un directorio vacío aún devolverá 1 línea. Y si llama ls -la, obtendrá tres líneas en el directorio. Desea ls -lA | wc -lomitir las entradas .y ... Sin embargo, seguirás siendo uno por uno.

1
Un directorio vacío devuelve 0 para mí
James Roth

2
Un enfoque corregido, que no contaría dos veces los archivos con nuevas líneas en el nombre, sería este: ls -q | wc -launque tenga en cuenta que este enfoque todavía no contará los archivos ocultos, y que los directorios se contarán.
godlygeek

31

Para una definición estrecha de archivo:

 find . -maxdepth 1 -type f | wc -l

Y, por supuesto, puede omitir el -maxdepth 1recuento de archivos de forma recursiva (o ajustarlo para la profundidad de búsqueda máxima deseada).
user7089

1
Si tiene un archivo cuyo nombre contiene una nueva línea, este enfoque lo contará incorrectamente dos veces.
godlygeek

77
Un enfoque corregido, que no contaría dos veces los archivos con nuevas líneas en el nombre, sería este:find -maxdepth 1 -type f -printf "\n" | wc -l
godlygeek

+1 Permitir archivos ocultos e ignora directorios
Michael Durrant

14
ls -1 | wc -l

...

$ ls --help | grep -- '  -1'
    -1                         list one file per line

...

$ wc --help | grep -- '  -l'
    -l, --lines            print the newline counts

PD: Nota ls - <número-> | wc - <letter-l>


10
La mayoría de las versiones de lshacer -1automáticamente cuando la salida es a una tubería.
Dennis Williamson

3
@Dennis, eso es interesante. No sabía que una aplicación podría decir que su salida se dirigía a una tubería.
xenoterracide

1
Edité esta versión ya que es más explícita. Sin embargo, sí ls usa -1 si está canalizado (pruébalo: ls | cat), encuentro que la sintaxis -1 es más explícita.
Gabe.

3
@xenoterracide: En Bash:[[ -p /dev/stdin ]] && echo "stdin is from a pipe"
Dennis Williamson el

2
En mis pruebas, fue significativamente más rápido proporcionar también la opción -f para evitar que ls clasifique los nombres de archivo. Desafortunadamente, aún obtienes la respuesta incorrecta si tus nombres de archivo contienen nuevas líneas.
Samuel Edwin Ward

10

Probablemente la respuesta más completa usando ls/ wcpair es

ls -Aq | wc -l

si desea contar archivos de puntos y

ls -q | wc -l

de otra manera.

  • -Aes contar archivos de puntos, pero omite .y ...
  • -qhacer lsreemplazar caracteres no gráficos, específicamente caracteres de nueva línea, con ?, haciendo que la salida sea 1 línea para cada archivo

Para obtener una salida de una línea desde el lsterminal (es decir, sin conectarlo wc), -1se debe agregar la opción.

(comportamiento de lsprobado con coreutils 8.23)


2
Como dijiste, -1no es necesario. En cuanto a "maneja las nuevas líneas de los nombres de archivos de manera sensata con la salida de la consola" , esto se debe al -qinterruptor (que debe usar en lugar de -bporque es portátil) que "obliga a escribir cada instancia de caracteres de nombre de archivo no imprimibles y caracteres <tab> como el carácter <question-mark> ('?'). Las implementaciones pueden proporcionar esta opción por defecto si la salida es a un dispositivo terminal ". Así por ejemplo, ls -Aq | wc -lpara contar todos los archivos / directorios o ls -qp | grep -c /para contar directorios único no ocultos, etc ...
don_crissti

Gracias por tu contribución. Cambiado -ba -q.
Frax

7

Si sabe que el directorio actual contiene al menos un archivo no oculto:

set -- *; echo "$#"

Esto es obviamente generalizable a cualquier glob.

En un guión, esto tiene el efecto secundario a veces desafortunado de sobrescribir los parámetros posicionales. Puede solucionarlo utilizando una subshell o con una función (versión Bourne / POSIX) como:

count_words () {
  eval 'shift; '"$1"'=$#'
}
count_words number_of_files *
echo "There are $number_of_files non-dot files in the current directory"

Una solución alternativa es $(ls -d -- * | wc -l). Si el glob es *, el comando se puede acortar a $(ls | wc -l). Analizar la salida de lssiempre me hace sentir incómodo, pero aquí debería funcionar siempre y cuando los nombres de los archivos no contengan nuevas líneas o lsse les escapen. Y $(ls -d -- * 2>/dev/null | wc -l)tiene la ventaja de manejar el caso de un globo no coincidente con gracia (es decir, devuelve 0 en ese caso, mientras que el set *método requiere pruebas complejas si el globo puede estar vacío).

Si los nombres de archivo pueden contener caracteres de nueva línea, se debe utilizar una alternativa $(ls -d ./* | grep -c /).

Cualquiera de esas soluciones que se basan en pasar la expansión de un globo lspuede fallar con un error de lista de argumentos demasiado largo si hay muchos archivos coincidentes.


1
¿Realmente quieres crear 13,923 parámetros posicionales? Y debe hacer su variable local localo eliminarla: eval $1=$#o simplemente usar echo $#y hacer number_of_files=$(count_words *).
Dennis Williamson el

1
@ Dennis: parte del punto era evitar la bifurcación. Supongo que no es una preocupación del siglo XXI. Ok, admito que ya no me importan los shells que no son POSIX, por lo que podría haber evitado la variable temporal.
Gilles

¿Por qué restaste uno $#(no lo habías hecho antes de la edición)?
Dennis Williamson el

@Dennis: sigo evitando una bifurcación (bueno, hace una diferencia en máquinas con una CPU lenta, como enrutadores) y pasando un nombre de variable como $1. Entonces, lo que quiero contar es la cantidad de parámetros que no son el primer parámetro. (No puedo usar shiftporque necesito mantener el nombre de la variable.) (Umm, ahora si hubieras preguntado por la primera línea ...)
Gilles

@ Dennis: ahora que lo pienso, puedo usarlo shiftsi es el momento adecuado.
Gilles

7

He encontrado du --inodesútil, pero no estoy seguro de qué versión durequiere. Debería ser sustancialmente más rápido que los enfoques alternativos que utilizan findy wc.

En Ubuntu 17.10, funciona lo siguiente:

du --inodes      # all files and subdirectories
du --inodes -s   # summary
du --inodes -d 2 # depth 2 at most

Combinar con | sort -nrpara ordenar descendente por número de inodos que contienen.


5

Si usamos ls / wc pair si estamos agregando -U, será mucho más rápido (no ordenar).

ls -AqU | wc -l

1
-USin embargo, es específico de GNU.
Stéphane Chazelas

4

Después de instalar el comando del árbol, simplemente escriba:

tree

Si también quieres archivos ocultos:

tree -a

Si está utilizando Debian / Mint / Ubuntu Linux, escriba el siguiente comando para instalar el comando del árbol:

sudo apt-get install tree

La opción -L se usa para especificar el nivel máximo de visualización del árbol de directorios. El comando de árbol no solo cuenta la cantidad de archivos, sino también la cantidad de directorios, considerando tantos niveles del árbol de directorios como desee.


Cuando escribo el árbol, obtengo una especie de salida del árbol en la pantalla del directorio en el que estoy pero no puedo ver dónde se muestra la cantidad de archivos.
charlesdarwin el

2
find -maxdepth 1 -type f -printf . | wc -c
  • -maxdepth 1lo hará no recursivo, findes recursivo por defecto
  • -type f incluirá solo archivos
  • -printf .Es un lindo toque. imprime un punto para cada archivo en lugar del nombre de archivo, y ahora puede manejar cualquier nombre de archivo y también guarda datos; solo tenemos que contar los puntos :)
  • | wc -c cuenta personajes

1

Sin tubería, sin copia de cadena, sin tenedor, simplemente golpea un forro

$ fcount() { local f i=0; for f in *; do let i++; done; echo $i; }; fcount

1
Da un valor de 1 si no hay archivos en el directorio. No cuenta archivos, cuenta archivos y directorios.
Steve

1

Aquí hay otra técnica similar a la que publicó Gilles :

word_count () { local c=("$@"); echo "${#c[@]}"; }
file_count=$(word_count *)

que crea una matriz con 13,923 elementos (si esa es la cantidad de archivos que hay).


¿Cuál es el punto de esa cmatriz? word_count() { echo "$#"; }seria suficiente. El objetivo de la solución @Gilles es almacenar el recuento en una variable devuelta para evitar tener que usar la sustitución de comandos (que implica una bifurcación y una tubería en capas diferentes a ksh93).
Stéphane Chazelas

1
find . -type f -maxdepth 1 |  wc -l 

Esto puede enumerar solo los archivos en el directorio actual.


find . -type fencontrará archivos en el directorio actual y también, recursivamente, en subdirectorios.
Dhag

0

Prueba esto, espero que esta respuesta te ayude

echo $((`ls -l | wc -l` -1 ))


0

Mejorando algunas respuestas dadas antes pero esta vez haciendo explícitamente.

$ tree -L 1 | tail -n 1 | cut -d " " -f 3

Vale la pena notar el uso de algunos comandos amados como taily cut. Además, tenga en cuenta que el árbol no está disponible de forma predeterminada. El comando anterior captura primero la información sobre el directorio en el nivel 1, luego obtiene la última línea tail -n 1donde está nuestro objetivo y termina cuttomando la tercera palabra.

Por ejemplo, ubicando en /:

/ $ tree -L 1
.
├── 1
├── bin -> usr/bin
├── boot
├── dev
├── etc
├── home
├── lib -> usr/lib
├── lib64 -> usr/lib64
├── lost+found
├── media
├── mnt
├── opt
├── proc
├── root
├── run
├── sbin -> usr/sbin
├── srv
├── sys
├── tmp
├── usr
└── var

20 directories, 1 file
/ $ tree -L 1 | tail -n 1
20 directories, 1 file
/ $ tree -L 1 | tail -n 1 | cut -d " " -f 3
1

Entonces, ¿qué hay de preguntar el número de directorios?



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.