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.