Calcul de la taille totale du fichier par extension dans le shell


13

Nous avons un ensemble de répertoires contenant des index lucene. Chaque index est un mélange de différents types de fichiers (différenciés par extension), par exemple:

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

(c'est environ 10 extensions différentes)

Nous aimerions obtenir un total par extension de fichier, par exemple:

.frq     21234
.fnm     34757
..

J'ai essayé différentes combinaisons de du / awk / xargs, mais il est difficile de faire exactement cela.


Vous avez la réponse à ce problème dans cet article: serverfault.com/questions/183431/…
Blueicefield

Voulez-vous connaître la taille totale de chaque type de fichier ou le nombre total de chaque type de fichier?
user9517

Taille totale du fichier s'il vous plaît.
barnybug

Réponses:


19

Pour une extension donnée, vous pouvez l'utiliser

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

pour obtenir la taille totale du fichier pour ce type.

Et après réflexion

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

Qui affichera la taille en octets de chaque type de fichier trouvé.


Merci, je cherchais quelque chose qui se résume par n'importe quelle extension (car ce serait pratique de trier ensuite par exemple)
barnybug

Vérifiez ma mise à jour.
user9517

grand merci. awk produit une sortie scientifique pour certains des nombres, peut-il être désactivé: .fdt 3.15152e + 10
barnybug

1
légèrement modifié pour donner simplement des nombres entiers: find. -name "* $ {ft}" -print0 | xargs -0 du -c | grep total | awk '{print $ 1}'
barnybug

1
Pourrait vouloir utiliser -inamepour rendre le cas de recherche d'extension de fichier insensible.
Aaron Copley

6

Avec bash version4, il vous suffit d'appeler find, lset ce awkn'est pas nécessaire:

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

Ce script ne fonctionne pas bien avec les noms de fichiers avec un caractère de tabulation. Passer read name sizeà read size nameet -printf "%f\t%s\n"à -printf "%s\t%f\n"devrait le corriger.
mat

1
Notez également que ce script ne fonctionne pas bien avec des fichiers sans extension. Il traitera le nom de fichier entier comme une extension. Ajoutez if [ "$name" == "$ext" ]; then ext="*no_extension*"; fiaprès ext=${name##*.}si vous devez l'empêcher. Cela mettra tous les fichiers sans extension dans le *no_extension*groupe (j'utilise *no_extension*parce que ce *n'est pas un caractère valide dans le nom de fichier)
mat

4

Chaque seconde colonne divisée par .et dernière partie (extension) enregistrée dans le tableau.

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

alors vous avez obtenu la taille totale de chaque extension en octets.

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

1

Extension du script Iain avec une version plus rapide pour travailler avec un grand nombre de fichiers.

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

J'ai résolu en utilisant ces deux commandes:

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

0

ma version de réponse à la question:

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.