Jak sortujesz dane wyjściowe według rozmiaru?

196

Jak sortujesz du -sh /dir/*według rozmiaru? Czytam jedną stronę, która mówi o użyciu, | sort -nale to oczywiście nie w porządku. Oto przykład, który jest zły.

[~]# 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
ksenoterracid
źródło
3
Wiedziałem, że już to widziałem . Najwyższej głosowało odpowiedź tam nie jest bardzo dobra, ale inni lepsze .
Gilles,
Przyjęta odpowiedź sort -hdziałała dla mnie w Ubuntu 16.04 LTS w sierpniu 2017 r. Najpierw znajduję zamontowany dysk przez cd /mnt(zamontowany przez UUID w fstab). Potem robię, du >~/dumnt.out a sort -h ~/dumnt.out >~/dumntsort.outpotem mogę zrobić `tail ~ / dumntsort.out, aby zobaczyć największe kosmiczne świnie.
SDsolar

Odpowiedzi:

252

Jeśli masz jądra GNU (wspólne w większości dystrybucji Linuksa), możesz użyć

du -sh -- * | sort -h

Ta -hopcja mówi, sortże dane wejściowe mają format czytelny dla człowieka (liczba z jednostką; 1024, dzięki czemu 1023 jest uważane za mniej niż 1 KB, co się zgadza z tym, co du -hrobi GNU ).

Ta funkcja została dodana do GNU Core Utilities 7.5 w sierpniu 2009 roku .

Uwaga:

Jeśli używasz starszej wersji systemu Mac OSX, musisz zainstalować coreutils z brew install coreutils, a następnie użyć gsortjako drop-in zamiennik sort.

Nowsze wersje macOS (zweryfikowane na Mojave) obsługują sort -hnatywnie.

Shawn J. Goff
źródło
27
uwaga: dodaj -rdo sortowania, jeśli chcesz duże na górze
ksenoterrakid
9
Na OSX można zainstalować coreutilsza pośrednictwem brewi dodać folder bin do PATHw swoim rc pliku i -hpowinny być dostępne.
kenorb
Och - dziękuję za przypomnienie -r. oznacza to, że nie potrzebuję tailpolecenia, aby zobaczyć wieprze.
SDsolar
47

Spróbuj użyć flagi -k, aby policzyć 1K bloków zamiast używania czytelnego dla człowieka. Następnie masz wspólną jednostkę i możesz łatwo wykonać sortowanie numeryczne.

du -ck | sort -n

Nie potrzebujesz wyraźnie jednostek ludzkich, ale jeśli tak, istnieje wiele sposobów, aby to zrobić. Wydaje się, że wielu używa powyższej techniki bloków 1K, a następnie wykonuje drugie połączenie do du.

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

Jeśli chcesz zobaczyć dodane jednostki KB, użyj:

du -k | sed -e 's_^\([0-9]*\)_\1 KB_' | sort -n
pboin
źródło
2
miło nie musieć instalować czegoś innego, aby uzyskać wyniki, których potrzebuję
taranaki
16

Jeśli nie masz najnowszej wersji jądra GNU , możesz wywoływać dubez -huzyskiwania sortowalnych danych wyjściowych i produkować przyjazne dla człowieka dane wyjściowe z niewielkim późniejszym przetwarzaniem. Ma to tę zaletę, że działa, nawet jeśli twoja wersja dunie ma -hflagi.

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}'

Jeśli chcesz sufiksów SI (tj. Wielokrotności 1000 zamiast 1024), zmień 1024 na 1000 w whiletreści pętli. (Należy pamiętać, że 1000 w stanie jest przeznaczone, aby uzyskać np. 1MZamiast 1000k.)

Jeśli masz duopcję wyświetlania rozmiarów w bajtach (np. -bLub -B 1- zauważ, że może to mieć efekt uboczny liczenia rzeczywistych rozmiarów plików, a nie użycia dysku), dodaj spację na początku s(tj. s=" kMGTEPYZ";) Lub dodaj if (x<1000) {return x} else {x/=1024}na początku humanfunkcja.

Wyświetlanie cyfry dziesiętnej dla liczb z zakresu 1–10 pozostawia się czytelnikowi jako ćwiczenie.

Gilles
źródło
Jest to jedyne gotowe rozwiązanie, które działało zarówno na systemie Linux, jak i Mac. Dziękuję bardzo!
Brian Graham,
9

Jeśli nie masz, sort -hmożesz to zrobić:

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/'

Pobiera listę du, oddziela sufiks i sortuje według tego. Ponieważ nie ma przyrostka dla <1K, pierwszy sed dodaje B (dla bajtu). Drugi sed dodaje separator między cyfrą a sufiksem. Trzeci sed przekształca G na Z, tak że jest większy niż M; jeśli masz pliki terabajtowe, musisz przekonwertować G na Y i T na Z. Na koniec sortujemy według dwóch kolumn, a następnie zastępujemy sufiks G.

Shawn J. Goff
źródło
Niesamowity wysiłek, ale nie jest to dla mnie bliskie.
jvriesem
6

W systemie OS X możesz zainstalować niezbędne coreutils za pośrednictwem Homebrew :

brew install coreutils

Z tym będziesz mieć gsort, który obejmuje -hparametr wiersza poleceń.

Roland
źródło
4

Ten mały skrypt Perla załatwia sprawę. Zapisz go jako duh(lub cokolwiek chcesz) i zadzwońduh /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;
ddeimeke
źródło
4

Ponieważ Mac OS X nie ma takiej -hopcji sort, próbowałem i uczyłem się, seda awkza pierwszą próbą:

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; }'

to długa linia. Po rozwinięciu jest to:

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; 

}'

Wypróbowałem to na Mac OS X Mavericks, Yosemite, Ubuntu 2014-04 z awkdomyślnym awk(czyli nawkdlatego, że oba wskazują awki ) lub gawk, i wszystkie działały.nawk/usr/bin/mawk

Oto próbka danych wyjściowych na komputerze 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

zamiast tego du -sk *widziałem w odpowiedzi @ Stefana, gdzie wyświetlana jest również suma całkowita, i bez przechodzenia przez punkt montowania systemu plików, za pomocądu -skcx *

nopole
źródło
1

Oto, czego używam na Ubuntu 10.04, CentOS 5.5, FreeBSD i Mac OS X.

Zapożyczyłem pomysł z www.geekology.co.za/ i earthinfo.org , a także z niesławnych kaczek z „Linux Server Hacks” O'Reilly. Nadal dostosowuję go do moich potrzeb. To wciąż jest w toku (jak w tym dniu pracowałem nad tym rano w pociągu.):

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

Oto wynik:

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:~ $
Stefan Lasiewski
źródło
Myślę, że miałeś na myśli du -cks -x *? (z gwiazdką)
nopole
Gwiazdka jest zbędna w tym zastosowaniu. Spróbuj.
Stefan Lasiewski
masz na myśli umieszczenie pierwszego zestawu kodu w pliku o nazwie ducks, chmod a+x ducksa następnie użyj go, ./ducksaby go uruchomić? Następnie widzę tylko całkowite użycie dysku, zarówno w systemie Mac OS X, jak i Ubuntu 2014-10. Próbowałem też wprowadzić ducks() { ...}definicję, .bashrca następnie użyć, ducksaby ją uruchomić, i to samo na Mac OS X, zobacz tylko wielką sumę
nopole
1

Zaszalej z tym skryptem -

$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;}'
jaypal singh
źródło
1

W przypadku braku GNU sort -hpowinno to działać w większości środowisk UNIX:

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 }'
friedl.otto
źródło
0

Ten obsługuje nazwy plików z białymi znakami lub apostrofami i działa w systemach, które nie obsługują xargs -dlub sort -h:

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

Co skutkuje w:

368K    diskmanagementd
392K    racoon
468K    coreaudiod
472K    securityd
660K    sshd
3.6M    php-fpm
Mark Crossfield
źródło
0

To posortuje dane wyjściowe w malejącym porządku według wielkości:

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

To posortuje dane wyjściowe w porządku rosnącym według wielkości:

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

PS: można tego użyć do sortowania według dowolnej kolumny, ale wartości tej kolumny powinny być w tym samym formacie

użytkownik5337995
źródło
1
Liczba sort -k1rnjest równoważna sort -rni po prostu sortuje numerycznie na podstawie początkowej sekwencji cyfr dziesiętnych w każdym wierszu. Nie rozumie zmiennoprzecinkowych, a ona nie rozumie k, M, G... przyrostków. 10,1k będzie uważane za większe niż 1,23G
Stéphane Chazelas
0

Testowane na Solarisie!

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

Spowoduje to rekurencyjne wyświetlanie wszystkich rozmiarów katalogów, na dole będzie największy katalog w gigabajtach, a na górze najmniejszy w kilobajtach.

Chuguniy
źródło
0

Największy jest na dole:

du -sh * | sort -h
Meskan
źródło
0

Komenda:

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

Wyjaśnienie:

  • Rozmiar listy wszystkich plików / folderów rekurencyjnie w bieżącym katalogu w formie czytelnej dla człowieka

du -ah .

  • Posortuj rozmiar czytelny dla człowieka, który jest obecny w pierwszej kolumnie i zachowaj największe 50

sort -k1 -h | tail -n 50

Rohan Ghige
źródło
-1

Aby posortować według rozmiaru w MB

du --block-size=MiB --max-depth=1 path | sort -n
lukmansh
źródło
Użytkownik chce du -hposortować dane wyjściowe (dane czytelne dla człowieka) posortowane numerycznie. Nie udzielasz na to odpowiedzi. Możesz także połączyć swoje konto UNIX-SE z innymi kontami na innych stronach SE.
Tonin
-2

Ten skrypt jest jeszcze łatwiejszy:

for i in G M K; do du -h -d1 / | grep [0-9]$i | sort -n; done
Hobit
źródło
-2

dla OSX

du -h -k  {PATH} | sort -n
Steve Greensides
źródło
nie jest po -kprostu anulowaniem, -ha jeśli tak, to w jaki sposób zapewnia to czytelny dla człowieka wynik wymagany przez PO.
Anthon