Come si ordina l'output per dimensione?


196

Come si ordina du -sh /dir/*per dimensione? Ho letto un sito che diceva l'uso | sort -nma ovviamente non è giusto. Ecco un esempio sbagliato.

[~]# 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
Sapevo di averlo visto prima . La risposta più votata non è molto buona, ma altre sono migliori .
Gilles,

La risposta accettata ha sort -hfunzionato per me in Ubuntu 16.04 LTS nell'agosto 2017. Per prima cosa trovo il mio drive montato da cd /mnt(montato da UUID in fstab). Poi faccio du >~/dumnt.out quindi sort -h ~/dumnt.out >~/dumntsort.outposso fare `tail ~ / dumntsort.out per vedere i maiali spaziali più grandi.
SDsolar,

Risposte:


252

Se hai coreutils GNU (comuni nella maggior parte delle distribuzioni Linux), puoi usare

du -sh -- * | sort -h

L' -hopzione dice sortche l'input è il formato leggibile dall'uomo (numero con unità; basato su 1024 in modo che 1023 sia considerato inferiore a 1K che corrisponde a ciò che du -hfa GNU ).

Questa funzione è stata aggiunta a GNU Core Utilities 7.5 nell'agosto 2009 .

Nota:

Se si utilizza una versione precedente di Mac OSX, è necessario installare coreutils con brew install coreutils, quindi utilizzare gsortcome sostituzione drop-in di sort.

Le versioni più recenti di macOS (verificate su Mojave) supportano in sort -hmodo nativo.


27
nota: aggiungi -rper ordinare, se vuoi quelli più grandi in alto
xenoterracide,

9
Su OSX è possibile installare coreutilstramite brewe aggiungere la cartella bin PATHnel file rc e -hdovrebbe essere disponibile.
Kenorb,

Oh, grazie per il promemoria -r. ciò significa che non ho bisogno del tailcomando per vedere i maiali.
SDsolar,

47

Prova a usare il flag -k per contare 1K blocchi invece di usare la lettura umana. Quindi, hai un'unità comune e puoi facilmente fare un ordinamento numerico.

du -ck | sort -n

Non hai esplicitamente bisogno di unità umane, ma se lo hai fatto, allora ci sono un sacco di modi per farlo. Molti sembrano usare la tecnica del blocco 1K sopra, quindi fare una seconda chiamata a du.

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

Se vuoi vedere le unità KB aggiunte, usa:

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

2
bello non dover installare qualcos'altro per ottenere i risultati di cui ho bisogno
taranaki

16

Se non hai una versione recente dei coreutils GNU , puoi chiamare dusenza -hottenere output ordinabili e produrre output a misura d'uomo con un po 'di post-elaborazione. Questo ha il vantaggio di funzionare anche se la tua versione di dunon ha il -hflag.

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

Se si desidera suffissi SI (ovvero multipli di 1000 anziché 1024), modificare da 1024 a 1000 nel whilecorpo del loop. (Si noti che 1000 nella condizione è previsto, in modo da ottenere ad esempio 1Manziché 1000k.)

Se hai duun'opzione per visualizzare le dimensioni in byte (ad es. -bOppure -B 1- nota che ciò potrebbe avere l'effetto collaterale di contare le dimensioni dei file effettive anziché l'utilizzo del disco), aggiungi uno spazio all'inizio di s(cioè s=" kMGTEPYZ";), oppure aggiungi if (x<1000) {return x} else {x/=1024}all'inizio di la humanfunzione.

La visualizzazione di una cifra decimale per i numeri nell'intervallo 1–10 viene lasciata come esercizio al lettore.


Questa è stata la soluzione pronta all'uso che ho trovato per funzionare sia su Linux che su Mac. Grazie mille!
Brian Graham,

9

Se non lo sort -hhai puoi farlo:

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

Questo ottiene la du list, separa il suffisso e ordina usando quello. Poiché non esiste alcun suffisso per <1K, il primo sed aggiunge una B (per byte). La seconda seduta aggiunge un delimitatore tra la cifra e il suffisso. La terza sed converte G in Z in modo che sia più grande di M; se hai file di terabyte, dovrai convertire G in Y e T in Z. Infine, ordiniamo per due colonne, quindi sostituiamo il suffisso G.


Sforzo fantastico, ma questo non si avvicina al lavoro per me.
jvriesem,

6

Su OS X, puoi installare i coreutils necessari tramite Homebrew :

brew install coreutils

Con questo avrai gsort, che include il -hparametro della riga di comando.


4

Questo piccolo script Perl fa il trucco. Salvalo come duh(o come vuoi) e chiamalo conduh /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

Poiché Mac OS X non ha l' -hopzione per sort, quindi ho provato e imparato sede awkper un primo tentativo:

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

è una lunga fila. Espanso, è:

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; 

}'

L'ho provato su Mac OS X Mavericks, Yosemite, Ubuntu 2014-04 con awkil valore predefinito awk(che è nawk, perché entrambi awke nawkpunto /usr/bin/mawk) o gawk, e tutti hanno funzionato.

Ecco un esempio dell'output su un 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

invece di du -sk *, ho visto nella risposta di @Stefan dove viene anche visualizzato il totale generale, e senza attraversare alcun punto di montaggio del filesystem, usandodu -skcx *


1

Ecco cosa uso su Ubuntu 10.04, CentOS 5.5, FreeBSD e Mac OS X.

Ho preso in prestito l'idea da www.geekology.co.za/ e earthinfo.org , oltre alle famigerate anatre di "Linux Server Hacks" di O'Reilly. Lo sto ancora adattando alle mie esigenze. Questo è ancora un work in progress (Come in, stavo lavorando su questo sul treno questa mattina.):

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

Ecco l'output:

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:~ $

Penso che volevi dire du -cks -x *? (con l'asterisco)
nopole il

L'asterisco è ridondante in questo utilizzo. Provaci.
Stefan Lasiewski,

intendi mettere il primo set di codice in un file chiamato ducks, chmod a+x duckse quindi usare ./ducksper eseguirlo? Quindi vedo solo l'utilizzo totale del disco, sia su Mac OS X che su Ubuntu 2014-10. Ho anche provato a inserire la ducks() { ...}definizione .bashrce poi a usarla ducksper eseguirla, e la stessa cosa su Mac OS X, vedere solo il totale generale
nopole

1

Impazzisci con questo script -

$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 assenza di GNU sort -h, questo dovrebbe funzionare nella maggior parte degli ambienti 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 }'

0

Questo gestisce i nomi di file con spazi bianchi o apostrofi e funziona su sistemi che non supportano xargs -do sort -h:

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

che si traduce in:

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

0

Questo ordinerà l'output in ordine decrescente di dimensioni:

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

Questo ordinerà l'output in ordine crescente di dimensioni:

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

PS: può essere utilizzato per ordinare in base a qualsiasi colonna, ma i valori delle colonne devono essere nello stesso formato


1
No. sort -k1rnequivale sort -rne ordina semplicemente numericamente in base alla sequenza iniziale di cifre decimali su ciascuna riga. Essa non capisce in virgola mobile, e non capisce i k, M, G... suffissi. 10.1k sarebbe considerato maggiore di 1.23G
Stéphane Chazelas il

0

Testato su 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

Questo produrrà ricorsivamente tutte le dimensioni della directory, in fondo sarà la directory più grande in Gigabyte e nella parte più piccola in Kilobyte.


0

Il più grande è in fondo:

du -sh * | sort -h

0

Comando:

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

Spiegazione:

  • Elenca le dimensioni di tutti i file / cartelle in modo ricorsivo nella directory corrente in forma leggibile dall'uomo

du -ah .

  • Ordina la dimensione leggibile dall'uomo che è presente nella prima colonna e mantieni il più grande 50

sort -k1 -h | tail -n 50


-1

Per ordinare per dimensione in MB

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

L'utente desidera ottenere l'output di du -h(output leggibile dall'uomo) in ordine numerico. Non stai fornendo una risposta a questo. Potresti anche voler collegare il tuo account UNIX-SE con gli altri account che hai sugli altri siti SE.
Tonin

-2

Questo script è ancora più semplice:

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

-2

per OSX

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

non è il -ksolo annullamento -he, in tal caso, in che modo ciò fornisce l'output leggibile dall'uomo richiesto dall'OP.
Anthon,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.