jueves, 6 de diciembre de 2018

Contar lineas idénticas

Hoy voy a plantear una solución sobre cómo realizar un conteo de lineas idénticas salidas de una aplicación o script.
Pongo un ejemplo, pero este método es aplicable a cualquier otro caso.
Objetivo: se quiere conocer cuántos ficheros hay dentro de un directorio por extensión.
El listado de ficheros se puede realizar fácilmente mediante find:
find . -type f -exec basename {} \;
Ahora vamos a quedarnos solo con la extensión:
for FICHERO in $(find . -type f -exec basename {} \;)
do
    echo "${FICHERO##*.}"
done
Si realizamos un sort de la salida, las lineas con idéntico texto aparecerán seguidas.
for FICHERO in $(find . -type f -exec basename {} \;)
do
    echo "${FICHERO##*.}"
done | sort
A continuación, con uniq -c se eliminarán las filas repetidas dejando una sola por cada texto diferente e indicando cuántas repeticiones había de cada texto:
for FICHERO in $(find . -type f -exec basename {} \;)
do
    echo "${FICHERO##*.}"
done | sort | uniq -c
Dando como salida:
      8 css
      3 eot
      1 gif
      5 html
     13 jpg
      9 js
      1 png
     75 scss
      3 svg
      3 ttf
      1 txt
      3 woff
      1 woff2
Ahora faltaría ordenar estas lineas por el número de la primera columna. Para ello, usaremos el comando sort -n para indicar que el método de ordenación sea numérico:
for FICHERO in $(find . -type f -exec basename {} \;)
do
    echo "${FICHERO##*.}"
done | sort | uniq -c | sort -n
Consiguiendo lo siguiente:
      1 gif
      1 png
      1 txt
      1 woff2
      3 eot
      3 svg
      3 ttf
      3 woff
      5 html
      8 css
      9 js
     13 jpg
     75 scss
Y si se desea cambiar el modo de ordenación, y que sea de mayor a menor basta con usar la opción -r de sort:
for FICHERO in $(find . -type f -exec basename {} \;)
do
    echo "${FICHERO##*.}"
done | sort | uniq -c | sort -nr
Quedando, por fin, lo que necesitábamos:
     75 scss
     13 jpg
      9 js
      8 css
      5 html
      3 woff
      3 ttf
      3 svg
      3 eot
      1 woff2
      1 txt
      1 png
      1 gif