Cuente el número total de archivos en un directorio particular con extensión específica


32

Quiero contar el número total de archivos en un directorio particular que termina con la extensión ".mp4".

Recibo el siguiente comando:

ls -F |grep -v / | wc -l

Cuenta todos los archivos en un directorio particular, pero quiero contar los archivos que terminan con la extensión .mp4.

¿Hay algún comando de Ubuntu para eso?


2
La respuesta simple, correcta y directa es @ louis-matthijssen one. ls -1El manejo de los caracteres de nueva línea hace, en este caso, sensible a la lssalida de análisis . El marcado es incorrecto para el uso de la bandera -R.
Rmano

Respuestas:


19

Aquí puedes hacerlo de esta manera

ls -lR /path/to/dir/*.jpg | wc -l

Esto te da cuenta


55
¿Por qué el -R? ¿Por qué hacer un completo statcuando solo necesitas el nombre de archivo? ¿Por qué no ls -1 *.jpg| wc -l? (ok, no funciona si tienes nombres de archivo con nuevas líneas. En ese caso te lo mereces ;-) ...)
Rmano

2
... y la pregunta era "contar el número de archivos en un directorio". Además, esto enumerará recursivamente todo el contenido de subdirectorios cuyo nombre termine en .jpg , no los archivos en subdirectorios que terminen en .jpg. ¿Alguna vez lo has probado?
Rmano

1
La pregunta dice "archivos en un directorio específico", lo que implica que no se desea la recursión de subdirectorios.
David Richerby

1
Esto también falla si hay demasiados archivos en el directorio (porque *.jpgestá expandido por el shell, no por ls) y si hay archivos cuyos nombres comienzan con guiones.
David Richerby

2
@DavidRicherby Omite los nombres que comienzan con .. Pero en realidad funciona bien con guiones en los nombres, excepto cuando /path/to/dires la cadena vacía o una ruta relativa que comienza con un guión. Pero me equivoqué antes de haber dicho que lsreemplaza los caracteres con ?. Eso sucede cuando stdout es una terminal, pero aquí la salida es una tubería, por lo que lsenvía todos los caracteres de los nombres de archivo a wc. Eso hace que esta respuesta sea incorrecta sin el indicador -qo -bpara cambiar ese comportamiento , porque los nombres de archivo pueden contener nuevas líneas. La respuesta de l0b0 está libre de estos problemas.
Eliah Kagan

42

Desafortunadamente, este problema benigno es difícil de resolver de una manera que admita todos los nombres de archivo y sea portátil. Esto es seguro (maneja archivos ocultos, rutas que contienen espacios, guiones e incluso líneas nuevas) y POSIX compatible :

find /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c

Si no desea que sea recursivo, simplemente agregue -maxdepth 1.

No debe analizar la lssalida.

Prueba:

$ cd -- "$(mktemp -d)"
$ touch -- -foo.mp4 .bar.mp4 .bat.mp4 'baz.mp4
> ban.mp4'
$ find . -mindepth 1 -type f -name "*.mp4" -exec printf x \; | wc -c
4

Compare con la respuesta aceptada :

$ ls -lR ./*.mp4 | wc -l
3

U otras sugerencias:

$ find . -name "*.mp4" | wc -l
5
$ ls -1 *.mp4 | wc -l
ls: invalid option -- '.'
Try 'ls --help' for more information.
0
$ find . -name "*.mp4" | wc -c # Answer fixed at a later time
51
$ find . -name "*.mp4" | wc -l
5
$ find . | grep -i ".mp4$" | wc -l
5
$ ls . | grep ".mp4$" | wc -l
3

2
Aunque esta respuesta es correcta y robusta, puede usarla en -printf xlugar de -exec printf x \;. Es decir: find /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c no es necesario -execel printfcomando externo , que si hay muchos archivos será muy lento , ya que finddebe bifurcar (2) una copia de sí mismo y luego ejecutar (2) /usr/bin/printf . Con -exec printf x \;eso, debe hacerse una vez para cada archivo .
Eliah Kagan

-printfno es compatible con POSIXfind , por lo que no lo utilicé.
l0b0

1
Ninguno de los dos es -mindepthy -maxdepth, que usaste.
Eliah Kagan

Buen punto, ¡no había captado eso!
l0b0

BSD findcontiene -mindepthy -maxdepthno contiene, -printfasí que aprecio la inclusión de ambos.
Joseph

11

Este busca, ordena y enumera todos los archivos por extensión en orden:

find . -type f | sed 's/.*\.//' | sort | uniq -c

¡Excelente! Simplemente agregaría un | sort -rnal final y tal vez un -mindepth 1si solo dir actual.
Pablo A

Y tal vez la tubería para head -nobtener la n superior.
Raman

una gran respuesta, muchas gracias
Dennis Golomazov

5

Creo que es muy simple como seguir los comandos.

$ find . -name "*.mp4" | wc -l
8

o

$ find . | grep -i ".mp4$" | wc -l
8

Creo que los comandos anteriores calculan el recuento de archivos y nombres de directorios *.mp4

así que le sugiero que use la -type fopción como findparámetro de la siguiente manera.

$ find . -name "*.mp4" -type f | wc -l
8

Además, ls -lRse puede usar comofind .


2

Podrías usar ls -1 *.mp4 | wc -l.

Esto mostrará una lista de todos los archivos que terminan en .mp4, imprimiendo cada archivo en una nueva línea ( ls -1 *.mp4), canalizando la salida a la wcque contará el número de nuevas líneas usando la -lbandera.


No estoy seguro de por qué esto fue rechazado, funciona
Panther

Como *.mp4el shell lo expande, no ls, esto fallará si hay tantos .mp4archivos en el directorio que la lista de ellos no se puede pasar lscomo argumentos.
David Richerby

@Rmana Pruébelo en un directorio que contiene un archivo llamado--.mp4
David Richerby

@DavidRicherby sí, tienes razón. --resolverá el segundo caso; el primero generará un mensaje de error (¡necesita muchos archivos!) y otra buena pregunta aquí. Casos de esquina, pero vale la pena notar, sí.
Rmano

1
@Rmano Sin agregar -qo -b, esto no tolera nuevas líneas en los nombres de archivo. Si corre ls -1 *.mp4desde su terminal sin tubería, lsve que su stdout es una terminal y toma-q como está implícito, imprimiendo ?s. Pero ese comportamiento desaparece cuando se canaliza la salida. ls -1 *.mp4 | wc -lcuenta en exceso si hay nuevas líneas. ls -1 *.mp4 | catmuestra lo que wc"ve". (Del mismo modo, -1está implícito cuando stdout no es una terminal, por lo que es opcional). ls -1q -- *.mp4 | wc -lCasi funciona, pero no con cero archivos .mp4.
Eliah Kagan

0

Esto debería darle la lista de archivos con .mp4

ls /path/to/directory | grep ".mp4$"

Cuando se combina con wc -lle dará cuenta

ls /path/to/directory | grep ".mp4$" | wc -l

si desea que la búsqueda incluya subdirectorios

ls -lR /path/to/directory | grep ".mp4$" | wc -l

no cuenta
Panther

me lo dio cuando lo usé conwc -l
Back.Slash

use ls sin tubería para grep y acortar su respuesta. Se ha publicado al menos dos veces ahora.
Panther

@ bodhi.zazen ls /directory/*.mp4hace que el shell expanda el globo y ejecute algo como ls /directory/file1.mp4 /directory/file2.mp4 ...Esto fallará si el directorio contiene más archivos mp4 de los que se pueden pasar como argumentos ls.
David Richerby

@DavidRicherby - no es mi comando ls, uso find;)
Panther


0
ls | grep --count \.csv$

Reemplazar (.csv con la extensión que desee)

Explicación: Creo que un esquema simple es buscar la lista de archivos y contar la extensión con grep. \.hacer coincidir .y $hacer coincidir la extensión al final de la línea. Funciona porque cuando la salida de ls se canaliza, se envía un nombre de archivo por línea, que puede verificar ejecutando:

ls | cat

1
Tenga en cuenta que en lugar de grep --count, también podría usar grep -c.
Mohsin Raza

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.