So finden Sie die gesamte Dateigröße, gruppiert nach Erweiterung

12

Ich arbeite an einem Cluster, der mit anderen Kollegen geteilt wird. Die Festplatte ist begrenzt (und war gelegentlich voll), daher bereinige ich gelegentlich meinen Teil. Ich möchte dies schnell tun, also mache ich dies bis jetzt, indem ich eine Liste von Dateien erstelle, die größer als 100 MB sind und älter als 3 Monate sind, und ich sehe, ob ich sie noch brauche.

Aber jetzt denke ich, dass es einen Ordner mit> 1000 kleineren Dateien geben könnte, den ich vermisse, also möchte ich einen einfachen Weg finden, um zu sehen, ob dies der Fall ist. Aus der Art und Weise, wie ich Daten generiere, würde es hilfreich sein, eine Liste der Gesamtgröße pro Erweiterung zu erhalten. Im Zusammenhang mit dieser Frage "Erweiterung" als alles hinter dem letzten Punkt im Dateinamen.

Angenommen, ich habe mehrere Ordner mit mehreren Dateien:

folder1/file1.bmp   40 kiB
folder1/file2.jpg   20 kiB
folder2/file3.bmp   30 kiB
folder2/file4.jpg    8 kiB

Ist es möglich, eine Liste der gesamten Dateigröße pro Dateierweiterung zu erstellen?

bmp 70 kiB
jpg 28 kiB

Dateien ohne Erweiterung interessieren mich nicht, daher können sie ignoriert oder in eine Kategorie eingeordnet werden.

Ich ging bereits durch die Menschen Seiten ls, duund find, aber ich weiß nicht , was das richtige Werkzeug für diesen Job ist ...

Gegenmodus
quelle
Diese Frage wäre auf codegolf.stackexchange.com nicht verkehrt :)
Doug McLean
@DougMcLean: Sie können es gerne dort posten. ;)

Antworten:

16

Auf einem GNU-System:

find . -name '?*.*' -type f -printf '%b.%f\0' |
  awk -F . -v RS='\0' '
    {s[$NF] += $1; n[$NF]++}
    END {for (e in s) printf "%15d %4d %s\n", s[e]*512, n[e], e}' |
  sort -n

Oder das Gleiche mit der perlVermeidung der -printfErweiterung von GNU find(verwendet immer noch eine GNU-Erweiterung -print0, aber diese wird heutzutage allgemeiner unterstützt):

find . -name '?*.*' -type f -print0 |
  perl -0ne '
    if (@s = stat$_){
      ($ext = $_) =~ s/.*\.//s;
      $s{$ext} += $s[12];
      $n{$ext}++;
    }
    END {
      for (sort{$s{$a} <=> $s{$b}} keys %s) {
        printf "%15d %4d %s\n",  $s{$_}<<9, $n{$_}, $_;
      }
    }'

Es gibt eine Ausgabe wie:

          12288    1 pnm
          16384    4 gif
         204800    2 ico
        1040384   17 jpg
        2752512   83 png

Wenn Sie möchten KiB, MiB... Suffixe, leiten Sie an numfmt --to=iec-i --suffix=B.

%b*512Gibt die Festplattennutzung an. Beachten Sie jedoch, dass Dateien, die mehrmals fest verknüpft sind, mehrmals gezählt werden, sodass möglicherweise eine Diskrepanz mit den duBerichten auftritt.

Stéphane Chazelas
quelle
Schlägt unter MacOS fehl (find: -printf: unbekannter Primär- oder Operator)
MichaelCodes
1
@MichaelCodes, ja -printfist spezifisch für GNU find, weshalb ich auf einem GNU-System sagte .
Stéphane Chazelas
@MichaelCodes, siehe Bearbeiten mit einer perlAlternative, die auch unter macOS funktionieren sollte.
Stéphane Chazelas
Was ist 1,4,2,17? Die Anzahl der Dateien für jeden Typ?
Jorge Cornejo Bellido
3

Hier ist eine andere Lösung:

find . -type f |  egrep -o "\.[a-zA-Z0-9]+$" | sort -u | xargs -I '%' find . -type f -name "*%" -exec du -ch {} + -exec echo % \; | egrep "^\.[a-zA-Z0-9]+$|total$" | uniq | paste - -

Der Teil, der die Erweiterungen erhält, ist:

find . -type f |  egrep -o "\.[a-zA-Z0-9]+$" | sort -u

Suchen Sie als nächstes nach den Dateien mit einer Erweiterung und drucken Sie sie auch auf dem Bildschirm aus:

xargs -I '%' find . -type f -name "*%" -exec du -ch {} + -exec echo % \;

Als nächstes wollen wir die Erweiterung und die Summe behalten:

egrep "^\.[a-zA-Z0-9]+$|total$" | uniq

und halten Sie es in der gleichen Zeile:

paste - -
Vahbuna
quelle
Funktioniert unter MacOS.
MichaelCodes
1

Nicht so schön wie Stephanes Lösung, aber Sie könnten es versuchen

find . -type f -name "*.png" -print0 | xargs -0r du -ch | tail -n1

Hier müssen Sie dies für jeden Dateityp ausführen.

Gegenmodus
quelle
1
Dies setzt voraus, dass nur wenige PNG-Dateien vorhanden sind, sodass nur ein duAufruf ausgeführt wird. Mit GNU xargsmöchten Sie das -rFlag hinzufügen, damit du nicht ausgeführt wird, wenn keine Datei vorhanden ist (andernfalls wird die Festplattennutzung des aktuellen Verzeichnisses verwendet). Möglicherweise möchten Sie ein hinzufügen -type foder ! type dvermeiden, dass die Dateien in Verzeichnissen gezählt werden, deren Name auf endet .png.
Stéphane Chazelas
Dies sucht nur nach einer bestimmten Erweiterung.
Rahul
Das habe ich geschrieben. Man musste es in ein Skript einschließen, das alle anwendbaren Erweiterungen durchläuft, um eine "vollständige" Lösung zu erhalten.
Gegenmodus