Usando group by en ls

1

Estoy usando cygwin en windows.

Deseo contar la cantidad de archivos jpeg, gif y png de una carpeta raíz.

Ahora puedo hacer:

ls . -1R | grep '.jpeg' |  wc -l
ls . -1R | grep '.gif' |  wc -l
ls . -1R | grep '.png' |  wc -l

¿Pero pensé que si había una group bysintaxis de tipo aquí podría hacer esto con un comando en lugar de tres?

¿Algun consejo?

dublintech
fuente

Respuestas:

2

trata eso:

ls | awk -F '.' '{print $2}' | sort | uniq -c | sort -n

explicación:

awk divide los archivos en el '.' y da salida a la segunda parte.

sort es ordenar todas las salidas.

uniq agrupa y cuenta por grupo

el segundo ordena los grupos por conteo

Probablemente habría una manera de mejorarlo haciendo que la salida awk sea la última parte, en lugar de la segunda parte. Pero olvidé cómo hacerlo, estoy seguro de que man awkpuede decírtelo.

repetición
fuente
1
El OP solo quiere jpg, png y gif. Además, está asumiendo que solo hay uno .en el nombre del archivo y que no hay espacios. Si realmente quieres usar gawk, imprime $NF, no $2.
terdon
gracias, $NFera lo que estaba buscando
reproducir
@ mauro.stettler no está mal, pero eso incluirá archivos sin extensión. Tampoco estoy seguro de para qué sirve -n al final del segundo tipo.
dublintech
1
el -nes interpretar números como números, y no como cadenas. de lo contrario, a 12se considera inferior a a 2.
reproducir
@ mauro.stettler ah cierto estoy usando gawk en windows. sort - n no funciona.
dublintech
1

También puedes usar find:

find . -name \*.jpeg -o -name \*.gif -o -name \*.png | sed 's/.*\.\([^.]\+\)/\1/' | sort | uniq -c

Esto devuelve el número de archivos bajo .con extensiones jpeg, gify pngmuy bien formateado con un resultado por línea:

 123 gif
 110 jpeg
1832 png

Agregue otras extensiones según sea necesario.

Explicación del comando:

  • find . -name \*.jpeg -o -name \*.gif -o -name \*.png

    busca archivos que coincidan con ' .jpeg' o ' .gif' o '* .png'.

  • sed 's/.*\.\([^.]\+\)/\1/'

    elimina el nombre de archivo y solo deja la extensión, por ejemplo, se file.gifconviertegif

  • sort

    ordenar extensiones. Después de este comando, la salida se ve así:

    gif
    gif
    gif
    (...)
    jpeg
    jpeg
    (...)
    png
    (...)
    
  • uniq -c

    informar el número de ocurrencias.

jaume
fuente
1

Estas soluciones funcionan para bash. No estoy seguro si desea el número de cada tipo de archivo o el total.

Si desea el número total de archivos de imagen, intente esto:

ls  {*jpg,*png,*gif} | wc -l

Esto significa lscualquier cosa que termine en jpg, pngo gify que atraviese wc.

Si quieres el número de cada uno, haz:

for n in jpg png gif; do echo -ne "$n\t"; ls *$n | wc -l; done

Este es un ciclo for. Se ejecutará 3 veces, una para cada uno de jpg png y gif. Cada vez que se ejecuta el bucle, la $nvariable tomará una de las extensiones como valor. Entonces, para la primera ejecución, ls *$nse ampliará a ls *jpg. echoesencialmente solo significa "imprimir". echo -nesignifica imprimir sin una nueva línea ( -n) y permitir caracteres de escape -e, esto me permite usar el carácter de tabulación \t.

Esto funcionará bien siempre que tenga al menos un archivo de cada tipo, de lo contrario se quejará (seguirá funcionando, solo se quejará). Para una versión un poco más robusta, intente esto:

for n in jpg png gif; do echo -ne "$n\t"; echo `ls *$n 2>/dev/null | wc -l ` || echo 0; done

Este bucle es similar al anterior pero comprueba si el lscomando devuelve un error. El ||operando en bash significa "Haz esto o, si esto no funcionó, haz eso ". Por lo tanto, le digo a bash, ls *jpgetc., y si no funciona, es decir, si no hay archivos con esa extensión, echo (print) 0. Esto 2>/dev/nullhace que se descarten los mensajes de error.


También puede usar awk (esta es una ligera modificación de la respuesta de mauro stettler, por lo que contará solo los archivos con las extensiones que le interesan):

ls {*.jpg,*.png,*.gif} | awk -F'.' '{print $NF}' | sort | unic -c 
terdon
fuente
Gracias. Eso funciona a través de un shell bash. ¿Puedes explicar qué significan los personajes? Solo así aprendo algo en lugar de copiar la respuesta.
dublintech
trabaja en bash. Mi error. He actualizado el comentario
dublintech
He añadido más información @dublintech. ¿Está claro ahora?
terdon
qué hacer -ne, $ n \ t, * $ n 2 / dev / null, '|| ¿media?
dublintech
@dublintech los explico en mi respuesta. 2>significa redirigir mensajes de error, /dev/nulles un dispositivo especial en * nix utilizado para descartar cosas. Es solo un truco que descarta los mensajes de error.
terdon