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.

barnybug
la source
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é.

Iain
la source
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
glenn jackman
la source
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
Selman Ulug
la source
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
MilesF
la source
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 }'
c4f4t0r
la source
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
Isterklister
la source
0

Essayez Crab ( http://etia.co.uk/ ) - c'est un utilitaire de ligne de commande qui vous permet d'interroger le système de fichiers à l'aide de SQL.

Jacek Lampart
la source