Calcular el tamaño total del archivo por extensión en shell


13

Tenemos un conjunto de directorios que contienen índices lucenos. Cada índice es una mezcla de diferentes tipos de archivos (diferenciados por extensión), por ejemplo:

0/index/_2z6.frq
0/index/_2z6.fnm
..
1/index/_1sq.frq
1/index/_1sq.fnm
..

(se trata de 10 extensiones diferentes)

Nos gustaría obtener un total por extensión de archivo, por ejemplo:

.frq     21234
.fnm     34757
..

He probado varias combinaciones de du / awk / xargs pero me resulta difícil hacer exactamente esto.


Tiene la respuesta para ese problema en esta publicación: serverfault.com/questions/183431/…
Blueicefield

¿Desea saber el tamaño total de cada tipo de archivo o el número total de cada tipo de archivo?
user9517

Tamaño total del archivo por favor.
barnybug

Respuestas:


19

Para cualquier extensión dada, un uso

find /path -name '*.frq' -exec ls -l {} \; | awk '{ Total += $5} END { print Total }'

para obtener el tamaño total del archivo para ese tipo.

Y después de pensar un poco

#!/bin/bash

ftypes=$(find . -type f | grep -E ".*\.[a-zA-Z0-9]*$" | sed -e 's/.*\(\.[a-zA-Z0-9]*\)$/\1/' | sort | uniq)

for ft in $ftypes
do
    echo -n "$ft "
    find . -name "*${ft}" -exec ls -l {} \; | awk '{total += $5} END {print total}'
done

Lo que generará el tamaño en bytes de cada tipo de archivo encontrado.


Gracias, estaba buscando algo que se resumiera por cualquier extensión (ya que sería útil ordenarlo, por ejemplo)
barnybug

Mira mi actualización.
user9517

muchas gracias. awk produce productos científicos para algunos de los números, puede esto ser desactivada: .fdt 3.15152e + 10
barnybug

1
ligeramente ajustado para dar números enteros simples: buscar. -name "* $ {ft}" -print0 | xargs -0 du -c | grep total | awk '{print $ 1}'
barnybug

1
Es posible que desee utilizar -inamepara hacer que la extensión de archivo no sea sensible a mayúsculas y minúsculas.
Aaron Copley

6

Con bash versión 4, solo necesita llamar find, lsy awkno es necesario:

declare -A ary

while IFS=$'\t' read name size; do 
  ext=${name##*.}
  ((ary[$ext] += size))
done < <(find . -type f  -printf "%f\t%s\n")

for key in "${!ary[@]}"; do 
  printf "%s\t%s\n" "$key" "${ary[$key]}"
done

Este script no funciona bien con nombres de archivo con caracteres de tabulación. Cambiar read name sizea read size namey -printf "%f\t%s\n"a -printf "%s\t%f\n"debería solucionarlo.
mate

1
Tenga en cuenta también que este script no funciona bien con archivos sin extensión. Tratará el nombre completo del archivo como extensión. Agregue if [ "$name" == "$ext" ]; then ext="*no_extension*"; fidespués ext=${name##*.}si necesita prevenirlo. Esto colocará todos los archivos sin extensión en el *no_extension*grupo (lo estoy usando *no_extension*porque *no es un carácter válido en el nombre del archivo)
mate

4

Cada segunda columna dividida por .y la última parte (extensión) guardada en la matriz.

#!/bin/bash

find . -type f -printf "%s\t%f\n" | awk '
{
 split($2, ext, ".")
 e = ext[length(ext)]
 size[e] += $1
}

END{
 for(i in size)
   print size[i], i
}' | sort -n

entonces tienes el tamaño total de cada extensión en bytes.

60055 gemspec
321991 txt
2075312 html
2745143 rb
13387264 gem
47196526 jar

1

Ampliando el script de Iain con una versión más rápida para trabajar con una gran cantidad de archivos.

#!/bin/bash

ftypes=$(find . -type f | grep -E ".*\.[a-zA-Z0-9]*$" | sed -e 's/.*\(\.[a-zA-Z0-9]*\)$/\1/' | sort | uniq)

for ft in $ftypes
do
    echo -ne "$ft\t"
    find . -name "*${ft}" -exec du -bcsh '{}' + | tail -1 | sed 's/\stotal//'
done


0

Resolví usando estos dos comandos:

FILES=$(find . -name '*.c')
stat -c %s ${FILES[@]} | awk '{ sum += $1 } END { print ".c" " " sum }'

0

mi versión de respuesta a la pregunta:

#!/bin/bash

date >  get_size.log
# Lists all files
find . -type f -printf "%s\t%f\n" | grep -E ".*\.[a-zA-Z0-9]*$" | sort -h | awk  '
{
        split($2, ext, ".")
        e = ext[length(ext)]
        # Checks that one extension could be found
        if(length(e) < length($2)) {
                # Check that file size are bigger than 0
                if($i > 0) {
                        # Check that extension not are integer
                        if(!(e ~/^[0-9]+$/)) {
                                size[e] += $1
                        }
                }
        }
        if(length(e) == length($2)) {
                size["blandat"] += $1
        }
}

END{
 for(i in size)
   print size[i], i
}' | sort -n >> get_size.log
echo
echo
echo The result are in file get_size.log

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.