Calcolo della dimensione totale del file per estensione nella shell


13

Abbiamo una serie di directory contenenti indici di lucene. Ogni indice è un mix di diversi tipi di file (differenziati per estensione), ad esempio:

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

(sono circa 10 diverse estensioni)

Vorremmo ottenere un totale per estensione del file, ad esempio:

.frq     21234
.fnm     34757
..

Ho provato varie combinazioni di du / awk / xargs ma trovo difficile fare esattamente questo.


Hai la risposta a questo problema in questo post: serverfault.com/questions/183431/…
Blueicefield

Vuoi conoscere la dimensione totale di ciascun tipo di file o il numero totale di ciascun tipo di file?
utente9517

Dimensione totale del file per favore.
Barnybug

Risposte:


19

Per ogni data estensione ti è utile

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

per ottenere la dimensione totale del file per quel tipo.

E dopo un po 'di riflessione

#!/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

Che produrrà la dimensione in byte di ciascun tipo di file trovato.


Grazie, stavo cercando qualcosa che riassumesse per qualsiasi estensione (come sarebbe utile poi ordinare per esempio)
Barnybug

Controlla il mio aggiornamento.
user9517

grazie mille. awk produce output scientifici per alcuni numeri, può essere disabilitato: .fdt 3.15152e + 10
barnybug

1
leggermente ottimizzato per dare solo numeri interi semplici: trova. -name "* $ {ft}" -print0 | xargs -0 du -c | totale grep | awk '{print $ 1}'
barnybug

1
Potrebbe essere utile utilizzare -inameper rendere insensibile la distinzione tra maiuscole e minuscole.
Aaron Copley

6

Con bash version4, basta alla chiamata find, lse awknon è necessario:

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

Questo script non funziona bene con i nomi di file con carattere di tabulazione. La modifica read name sizein read size namee -printf "%f\t%s\n"to -printf "%s\t%f\n"dovrebbe risolverlo.
matt

1
Nota anche che questo script non funziona bene con i file senza estensione. Tratterà l'intero nome del file come estensione. Aggiungi if [ "$name" == "$ext" ]; then ext="*no_extension*"; fidopo ext=${name##*.}se devi prevenirlo. Questo metterà tutti i file senza estensione nel *no_extension*gruppo (sto usando *no_extension*perché *non è un carattere valido nel nome del file)
matt

4

Ogni seconda colonna divisa per .e ultima parte (estensione) salvata nella matrice.

#!/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

allora hai tutte le dimensioni totali di ogni estensione in byte.

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

1

Estensione dello script di Iain con una versione più veloce per lavorare con un gran numero di file.

#!/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

Ho risolto usando questi due comandi:

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

0

la mia versione di risposta alla domanda:

#!/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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.