it-swarm.it

Come si ordina l'output per dimensione?

Come si ordina du -sh /dir/* per dimensione? Ho letto un sito che diceva l'uso | sort -n ma 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
209
xenoterracide

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

du -sh -- * | sort -h

Il -h L'opzione dice a sort che 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 cosa GNU du -h lo fa).

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

Nota:

Se stai utilizzando una versione precedente di Mac OSX, devi installare coreutils con brew install coreutils , Quindi usa gsort come sostituzione drop-in di sort.

Le versioni più recenti di macOS (verificate su Mojave) supportano sort -h nativamente.

268
Shawn J. Goff

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
49
pboin

Se non hai un versione recente di GNU coreutils , puoi chiamare du senza -h Per ottenere un output ordinabile, e produrre output a misura d'uomo con un po 'di postelaborazione. Questo ha il vantaggio di funzionare anche se la tua versione di du non ha il flag -h.

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 corpo del loop while. (Si noti che 1000 nella condizione è previsto, in modo da ottenere ad esempio 1M Anziché 1000k.)

Se du ha un'opzione per visualizzare le dimensioni in byte (ad esempio -b O -B 1, Tieni presente che ciò potrebbe avere l'effetto collaterale di contare le dimensioni effettive dei file anziché l'utilizzo del disco) , aggiungi uno spazio all'inizio di s (ovvero s=" kMGTEPYZ";) oppure aggiungi if (x<1000) {return x} else {x/=1024} all'inizio della funzione human.

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

Se non hai sort -h 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). Il secondo sed 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.

9
Shawn J. Goff

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

brew install coreutils

Con questo avrai gsort, che include -h parametro della riga di comando.

6
Roland

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

Poiché Mac OS X non ha il -h opzione per sort, quindi ho provato e imparato sed e awk per 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 awk come predefinito awk (ovvero nawk, perché sia ​​awk che nawk punta a /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, usando du -skcx *

4
nonopolarity

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 , così come il famigerato anatre da "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:

[email protected]:~ $ ducks
32M src
42M .cpan
43M .macports
754M    doc
865M    Work
1G  .Trash
4G  Library
17G Downloads
30G Documents
56G total

[email protected]:~ $
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 }'
1
friedl.otto

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
jaypal singh

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

0
Rohan Ghige

Il più grande è in fondo:

du -sh * | sort -h
0
Meskan

Questo gestisce i nomi di file con spazi bianchi o apostrofi e funziona su sistemi che non supportano xargs -d o 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
Mark Crossfield

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 di quella colonna devono essere nello stesso formato

0
user5337995

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 di directory, in fondo sarà la directory più grande in Gigabyte e nella parte più piccola in Kilobyte.

0
Chuguniy