Wie sortieren Sie Ihre Ausgabe nach Größe?


196

Wie sortieren Sie du -sh /dir/*nach Größe? Ich habe eine Seite gelesen, auf der die Verwendung angegeben ist, | sort -naber das ist offensichtlich nicht richtig. Hier ist ein falsches Beispiel.

[~]# du -sh /var/* | sort -n
0       /var/mail
1.2M    /var/www
1.8M    /var/tmp
1.9G    /var/named
2.9M    /var/run
4.1G    /var/log
8.0K    /var/account
8.0K    /var/crash
8.0K    /var/cvs
8.0K    /var/games
8.0K    /var/local
8.0K    /var/nis
8.0K    /var/opt
8.0K    /var/preserve
8.0K    /var/racoon
12K     /var/aquota.user
12K     /var/portsentry
16K     /var/ftp
16K     /var/quota.user
20K     /var/yp
24K     /var/db
28K     /var/empty
32K     /var/lock
84K     /var/profiles
224M    /var/netenberg
235M    /var/cpanel
245M    /var/cache
620M    /var/lib
748K    /var/spool

3
Ich wusste, dass ich das schon mal gesehen hatte . Die am höchsten bewertete Antwort ist dort nicht sehr gut, aber andere sind besser .
Gilles

Die akzeptierte Antwort sort -hhat bei mir in Ubuntu 16.04 LTS im August 2017 funktioniert. Zuerst finde ich mein gemountetes Laufwerk von cd /mnt(gemountet von UUID in fstab). Dann mache ich du >~/dumnt.out dann sort -h ~/dumnt.out >~/dumntsort.outkann ich `tail ~ / dumntsort.out machen, um die größten Raumschweine zu sehen.
SDsolar

Antworten:


252

Wenn Sie GNU-Coreutils haben (die in den meisten Linux-Distributionen üblich sind), können Sie diese verwenden

du -sh -- * | sort -h

Die -hOption gibt an, sortdass die Eingabe vom Menschen lesbar ist (Zahl mit Einheit; 1024-basiert, sodass 1023 als weniger als 1 KB angesehen wird, was dem entspricht, was GNU du -htut).

Diese Funktion wurde im August 2009 zu GNU Core Utilities 7.5 hinzugefügt .

Hinweis:

Wenn Sie eine ältere Version von Mac OSX verwenden, müssen Sie coreutils mit brew install coreutils,installieren und dann gsortals Ersatz für verwenden sort.

Neuere Versionen von macOS (auf Mojave verifiziert) unterstützen sort -hnativ.


27
hinweis: -rzur
sortierung

9
Unter OSX können Sie coreutilsüber brewden Ordner bin installieren und ihn PATHin Ihre RC- Datei einfügen. Er-h sollte verfügbar sein.
Kenorb

Oh, danke für die Erinnerung. Das heißt, ich brauche den tailBefehl nicht, um die Schweine zu sehen.
SDsolar

47

Verwenden Sie das Flag -k, um 1-KByte-Blöcke anstelle von lesbaren Blöcken zu zählen. Dann haben Sie eine gemeinsame Einheit und können ganz einfach eine numerische Sortierung durchführen.

du -ck | sort -n

Sie brauchen nicht explizit menschliche Einheiten, aber wenn ja, dann gibt es eine Reihe von Möglichkeiten, dies zu tun. Viele scheinen die oben beschriebene 1K-Blocktechnik zu verwenden und dann einen zweiten Aufruf an du zu senden.

https://serverfault.com/questions/62411/how-can-i-sort-du-h-output-by-size

Wenn Sie die hinzugefügten KB-Einheiten sehen möchten, verwenden Sie:

du -k | sed -e 's_^\([0-9]*\)_\1 KB_' | sort -n

2
schön, nicht noch etwas installieren zu müssen, um die Ergebnisse zu erhalten, die ich brauche
taranaki

16

Wenn Sie keine neuere Version von GNU coreutils haben , können Sie duohne Aufruf -hsortierbare Ausgabe erhalten und mit ein wenig Nachbearbeitung eine benutzerfreundliche Ausgabe erzeugen. Dies hat den Vorteil, dass es funktioniert, auch wenn Ihre Version von dudie -hFlagge nicht hat .

du -k | sort -n | awk '
    function human(x) {
        if (x<1000) {return x} else {x/=1024}
        s="kMGTEPZY";
        while (x>=1000 && length(s)>1)
            {x/=1024; s=substr(s,2)}
        return int(x+0.5) substr(s,1,1)
    }
    {gsub(/^[0-9]+/, human($1)); print}'

Wenn Sie SI-Suffixe (dh ein Vielfaches von 1000 anstelle von 1024) wünschen, ändern Sie 1024 in 1000 im whileSchleifenkörper. (Beachten Sie, dass 1000 in der Bedingung vorgesehen ist, so dass Sie zB 1Meher als erhalten 1000k.)

Wenn Sie dudie Option zum Anzeigen von Größen in Byte haben (z. B. -boder -B 1- Beachten Sie, dass dies den Nebeneffekt haben kann, dass die tatsächlichen Dateigrößen anstelle der Festplattennutzung gezählt werden), fügen Sie am Anfang von s(dh s=" kMGTEPYZ";) ein Leerzeichen oder if (x<1000) {return x} else {x/=1024}am Anfang von (dh ) ein die humanFunktion.

Die Anzeige einer Dezimalstelle für Zahlen im Bereich von 1 bis 10 wird dem Leser als Übung überlassen.


Dies ist die Standardlösung, die ich für Linux und Mac gefunden habe. Vielen Dank!
Brian Graham

9

Wenn Sie nicht haben sort -h, können Sie dies tun:

du -sh * | sed 's/\([[:digit:]]\)\t/\1B\t/' | sed 's/\(.\t\)/\t\1/' | sed 's/G\t/Z\t/' | sort -n -k 2d,2 -k 1n,1 | sed 's/Z\t/G\t/'

Dies ruft die du-Liste ab, trennt das Suffix und sortiert danach. Da es für <1 KB kein Suffix gibt, fügt der erste sed ein B (für Byte) hinzu. Der zweite Satz fügt ein Trennzeichen zwischen der Ziffer und dem Suffix ein. Das dritte sed wandelt G in Z um, so dass es größer als M ist; Wenn Sie Terabyte-Dateien haben, müssen Sie G in Y und T in Z konvertieren. Schließlich sortieren wir nach den beiden Spalten und ersetzen dann das Suffix G.


Großartige Anstrengung, aber das kommt der Arbeit für mich nicht nahe.
Jvriesem

6

Unter OS X können Sie die benötigten Coreutils über Homebrew installieren :

brew install coreutils

Damit haben Sie gsort, die den -hBefehlszeilenparameter enthält .


4

Dieses kleine Perl-Skript erledigt den Trick. Speichern Sie es als duh(oder was auch immer Sie wollen) und rufen Sie es mitduh /dir/*

#!/usr/bin/perl -w
use strict;

my @line;

sub to_human_readable {
        my ($number) = @_;
        my @postfix = qw( k M G T P );
        my $post;
        my $divide = 1;
        foreach (@postfix) {
                $post = $_;
                last if (($number / ($divide * 1024)) < 1);
                $divide = $divide * 1024;
        }
        $number = int($number/$divide + 0.5);
        return $number . $post;
}

sub trimlengthright {
        my ($txt, $len) = @_;
        if ( length($txt) >= $len ) {
                $txt = substr($txt,0,$len - 1) . " ";
        } else {
                $txt = $txt . " " x ($len - length($txt));
        }
        return $txt;
}

sub trimlengthleft {
        my ($txt, $len) = @_;
        if ( length($txt) >= $len ) {
                $txt = substr($txt,0,$len - 1) . " ";
        } else {
                $txt = " " x ($len - length($txt)) . $txt;
        }
        return $txt;
}

open(DF,"du -ks @ARGV | sort -n |");
while (<DF>) {
        @line = split;
        print &trimlengthleft(&to_human_readable($line[0]),5)," "; # size
        print &trimlengthright($line[1],70),"\n"; # directory
}
close DF;

4

Da Mac OS X nicht die -hOption für hat sort, habe ich sedund awkfür einen ersten Versuch versucht und gelernt :

du -sk * | sort -g | awk '{ numBytes = $1 * 1024; numUnits = split("B K M G T P", unit); num = numBytes; iUnit = 0; while(num >= 1024 && iUnit + 1 < numUnits) { num = num / 1024; iUnit++; } $1 = sprintf( ((num == 0) ? "%6d%s " : "%6.1f%s "), num, unit[iUnit + 1]); print $0; }'

Es ist eine lange Schlange. Erweitert ist es:

du -sk * | sort -g | awk '{ 

    numBytes = $1 * 1024; 
    numUnits = split("B K M G T P", unit); 
    num = numBytes; 
    iUnit = 0; 

    while(num >= 1024 && iUnit + 1 < numUnits) { 
        num = num / 1024; 
        iUnit++; 
    } 

    $1 = sprintf( ((num == 0) ? "%6d%s " : "%6.1f%s "), num, unit[iUnit + 1]);
    print $0; 

}'

Ich habe es unter Mac OS X Mavericks, Yosemite und Ubuntu 2014-04 mit awkder Standardeinstellung awk( nawkda beide awkund auf nawkzeigen /usr/bin/mawk) oder gawk versucht, und alle haben funktioniert.

Hier ist ein Beispiel für die Ausgabe auf einem Mac:

     0B  bar
     0B  foo
   4.0K  wah
  43.0M  Documents
   1.2G  Music
   2.5G  Desktop
   4.7G  Movies
   5.6G  VirtualBox VMs
   9.0G  Dropbox
  11.7G  Library
  21.2G  Pictures
  27.0G  Downloads

Stattdessen habe du -sk *ich in @ Stefans Antwort gesehen, wo auch die Gesamtsumme angezeigt wird, und zwar ohne einen Dateisystem-Mount-Punkt zu durchlaufendu -skcx *


1

Folgendes verwende ich unter Ubuntu 10.04, CentOS 5.5, FreeBSD und Mac OS X.

Ich habe die Idee von www.geekology.co.za/ und earthinfo.org sowie die berüchtigten Enten von "Linux Server Hacks" von O'Reilly ausgeliehen. Ich passe es immer noch an meine Bedürfnisse an. Dies ist noch in Arbeit (Wie in, ich habe heute Morgen im Zug daran gearbeitet.):

#! /usr/bin/env bash
ducks () {
    du -cks -x | sort -n | while read size fname; do
        for unit in k M G T P E Z Y; do
            if [ $size -lt 1024 ]; then
                echo -e "${size}${unit}\t${fname}"
                break
            fi
            size=$((size/1024))
        done
    done
}
ducks > .ducks && tail .ducks

Hier ist die Ausgabe:

stefan@darwin:~ $ ducks
32M src
42M .cpan
43M .macports
754M    doc
865M    Work
1G  .Trash
4G  Library
17G Downloads
30G Documents
56G total

stefan@darwin:~ $

Ich denke du meintest du -cks -x *? (mit dem
sternchen

Das Sternchen ist in dieser Verwendung überflüssig. Versuche es.
Stefan Lasiewski

Meinen Sie damit, den ersten Satz von Code in eine Datei mit dem Namen ducksund dann chmod a+x ducksund dann ./ducksmit auszuführen? Dann sehe ich nur die Gesamtbelegung der Festplatte, sowohl unter Mac OS X als auch unter Ubuntu 2014-10. Ich habe auch versucht, die ducks() { ...}Definition in .bashrcund dann duckszum Ausführen zu verwenden, und das Gleiche unter Mac OS X, sehen Sie nur die Gesamtsumme
Nopole

1

Verrückt werden mit diesem Skript -

$du -k ./* | 
> sort -nr |
> awk '
> {split("KB,MB,GB",size,",");}
> {x = 1;while ($1 >= 1024) {$1 = $1 / 1024;x = x + 1} $1 = sprintf("%-4.2f%s", $1, size[x]); print $0;}'

1

In Abwesenheit von GNU sort -hsollte dies in den meisten UNIX-Umgebungen funktionieren:

join -1 2 -2 2 <(du -sk /dir/* 2>/dev/null | sort -k2,2) <(du -sh /dir/* 2>/dev/null | sort -k2,2) | sort -nk2,2 | awk '{ print $3 "\t" $1 }'

0

Dieser behandelt Dateinamen mit Leerzeichen oder Apostrophen und funktioniert auf Systemen, die Folgendes nicht unterstützen xargs -doder sort -h:

du -s * | sort -n | cut -f2 | tr '\n' '\0' | xargs -0 -I {} du -sh "{}"

was in ... endet:

368K    diskmanagementd
392K    racoon
468K    coreaudiod
472K    securityd
660K    sshd
3.6M    php-fpm

0

Dadurch wird die Ausgabe in absteigender Reihenfolge der Größe sortiert:

du -sh /var/* | sort -k 1rn

Dadurch wird die Ausgabe in aufsteigender Reihenfolge der Größe sortiert:

du -sh /var/* | sort -k 1n

PS: Dies kann verwendet werden, um nach jeder Spalte zu sortieren, aber die Spaltenwerte sollten dasselbe Format haben


1
Die Zahl sort -k1rnentspricht sort -rnder ersten Folge von Dezimalstellen in jeder Zeile und wird nur numerisch sortiert. Es versteht nicht , Punkt schwimmen, und es versteht nicht den k, M, G... Suffixe. 10.1k würde als größer als 1.23G betrachtet werden
Stéphane Chazelas

0

Getestet unter Solaris!

du -kh | sort -nk1 | grep [0-9]K && du -kh | sort -nk1 | grep [0-9]M && du -kh | sort -nk1 | grep [0-9]G

Dadurch werden alle Verzeichnisgrößen rekursiv ausgegeben. Unten wird das größte Verzeichnis in Gigabyte und oben das kleinste in Kilobyte angezeigt.



0

Befehl:

du -ah . | sort -k1 -h | tail -n 50

Erläuterung:

  • Listengröße aller Dateien / Ordner rekursiv im aktuellen Verzeichnis in lesbarer Form

du -ah .

  • Sortieren Sie die für Menschen lesbare Größe, die in der ersten Spalte vorhanden ist, und behalten Sie die größten 50 bei

sort -k1 -h | tail -n 50


-1

Sortieren nach Größe in MB

du --block-size=MiB --max-depth=1 path | sort -n

Der Benutzer möchte die Ausgabe von du -h(von Menschen lesbare Ausgabe) numerisch sortiert bekommen. Darauf geben Sie keine Antwort. Möglicherweise möchten Sie auch Ihr UNIX-SE-Konto mit den anderen Konten verknüpfen, die Sie auf den anderen SE-Standorten haben.
Tonin

-2

Dieses Skript ist noch einfacher:

for i in G M K; do du -h -d1 / | grep [0-9]$i | sort -n; done

-2

für OSX

du -h -k  {PATH} | sort -n

ist nicht -knur das Abbrechen, -hund wenn ja, wie liefert dies die vom OP angeforderte vom Menschen lesbare Ausgabe.
Anthon
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.