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.


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.


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

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

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


0

Ich löste mit diesen beiden Befehlen:

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

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.