Berechnung der Gesamtdateigröße anhand der Erweiterung in der Shell

13

Wir haben eine Reihe von Verzeichnissen, die Lucene-Indizes enthalten. Jeder Index ist eine Mischung aus verschiedenen Dateitypen (differenziert nach Erweiterung), zB:

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

(es geht um 10 verschiedene Erweiterungen)

Wir möchten eine Gesamtsumme nach Dateierweiterung erhalten, zB:

.frq     21234
.fnm     34757
..

Ich habe verschiedene Kombinationen von du / awk / xargs ausprobiert, finde es aber schwierig, genau das zu tun.

Scheunenwanze
quelle
Sie haben die Antwort für dieses Problem in diesem Beitrag: serverfault.com/questions/183431/…
Blueicefield
Möchten Sie die Gesamtgröße jedes Dateityps oder die Gesamtanzahl jedes Dateityps wissen?
user9517
Gesamtgröße der Datei bitte.
Barnybug

Antworten:

19

Für jede gegebene Erweiterung können Sie eine verwenden

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

um die gesamte Dateigröße für diesen Typ zu erhalten.

Und nach einigem Nachdenken

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

Welches die Größe in Bytes jedes gefundenen Dateityps ausgibt.

Iain
quelle
Vielen Dank, suchte nach etwas, das von jeder Erweiterung zusammengefasst wird (wie es zum Beispiel praktisch wäre, dann zu sortieren)
Barnybug
Überprüfen Sie mein Update.
Benutzer9517
vielen Dank. awk produziert wissenschaftliche Ausgaben für einige der Zahlen. Kann diese deaktiviert werden: .fdt 3.15152e + 10
barnybug
1
leicht angepasst, um nur einfache Ganzzahlen zu erhalten: find. -name "* $ {ft}" -print0 | xargs -0 du -c | grep total | awk '{print $ 1}'
Barnybug
1
-inameMöchte möglicherweise verwenden , um die Groß- und Kleinschreibung der Dateierweiterung zu ignorieren.
Aaron Copley
6

Mit bash version4, müssen Sie nur auf Anruf find, lsund awknicht notwendig:

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
quelle
Dieses Skript funktioniert nicht gut mit Dateinamen mit Tabulatorzeichen. Das Wechseln read name sizezu read size nameund -printf "%f\t%s\n"nach -printf "%s\t%f\n"sollte das Problem beheben.
Matt
1
Beachten Sie auch, dass dieses Skript mit Dateien ohne Erweiterung nicht gut funktioniert. Der gesamte Dateiname wird als Erweiterung behandelt. Fügen Sie if [ "$name" == "$ext" ]; then ext="*no_extension*"; fidanach hinzu, ext=${name##*.}wenn Sie dies verhindern müssen. Dadurch werden alle Dateien ohne Dateierweiterung in eine *no_extension*Gruppe eingeteilt (ich verwende, *no_extension*weil der *Dateiname kein gültiges Zeichen enthält)
matt
4

Jede zweite Spalte, aufgeteilt nach .und letzter Teil (Erweiterung), gespeichert im Array.

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

dann hast du jede erweiterung gesamtgröße in bytes.

60055 gemspec
321991 txt
2075312 html
2745143 rb
13387264 gem
47196526 jar
Selman Ulug
quelle
1

Erweiterung von Iains Skript um eine schnellere Version für die Arbeit mit einer großen Anzahl von Dateien.

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

Ich löste mit diesen beiden Befehlen:

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

Meine Version der Antwort auf die Frage:

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

Try Crab ( http://etia.co.uk/ ) - ein Befehlszeilenprogramm, mit dem Sie das Dateisystem mit SQL abfragen können.

Jacek Lampart
quelle