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.

barnybug
fuente
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.

Iain
fuente
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
Glenn Jackman
fuente
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
Selman Ulug
fuente
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
MilesF
fuente
0

Resolví usando estos dos comandos:

FILES=$(find . -name '*.c')
stat -c %s ${FILES[@]} | awk '{ sum += $1 } END { print ".c" " " sum }'
c4f4t0r
fuente
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
Isterklister
fuente
0

Pruebe Crab ( http://etia.co.uk/ ): es una utilidad de línea de comandos que le permite consultar el sistema de archivos mediante SQL.

Jacek Lampart
fuente