Como você classifica a saída por tamanho?

196

Como você classifica du -sh /dir/*por tamanho? Li um site que dizia uso, | sort -nmas obviamente isso não está certo. Aqui está um exemplo que está errado.

[~]# 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
xenoterracida
fonte
3
Eu sabia que tinha visto isso antes . A resposta mais votada não é muito boa, mas outras são melhores .
Gilles
A resposta aceita sort -hfuncionou para mim no Ubuntu 16.04 LTS em agosto de 2017. Primeiro, localizo minha unidade montada por cd /mnt(montada por UUID no fstab). Então eu faço du >~/dumnt.out , sort -h ~/dumnt.out >~/dumntsort.outentão eu posso fazer `tail ~ / dumntsort.out para ver os maiores porcos espaciais.
SDSolar 17/08/19

Respostas:

252

Se você possui GNU coreutils (comum na maioria das distribuições Linux), pode usar

du -sh -- * | sort -h

A -hopção informa sortque a entrada é o formato legível por humanos (número com unidade; com base em 1024, para que 1023 seja considerado menor que 1K, o que coincide com o que o GNU du -hfaz).

Este recurso foi adicionado ao GNU Core Utilities 7.5 em agosto de 2009 .

Nota:

Se você estiver usando uma versão mais antiga do Mac OSX, precisará instalar o coreutils com brew install coreutils, e usá-lo gsortcomo substituto do sort.

As versões mais recentes do macOS (verificadas no Mojave) oferecem suporte sort -hnativo.

Shawn J. Goff
fonte
27
note: adicione -rà classificação, se você quiser os maiores no topo
xenoterracide
9
No OSX você pode instalar coreutilsvia brewe adicionar a pasta bin ao seu PATHem sua rc arquivo, e -hdeve estar disponível.
kenorb
Oh - obrigado pelo lembrete -r. isso significa que não preciso do tailcomando para ver os porcos.
SDSolar 17/08/2017
47

Tente usar o sinalizador -k para contar blocos de 1K em vez de usar legível por humanos. Então, você tem uma unidade comum e pode facilmente fazer uma classificação numérica.

du -ck | sort -n

Você não precisa explicitamente de unidades humanas, mas, se precisar, existem várias maneiras de fazê-lo. Muitos parecem usar a técnica de bloqueio de 1K acima e, em seguida, fazem uma segunda chamada para du.

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

Se você deseja ver as unidades de KB adicionadas, use:

du -k | sed -e 's_^\([0-9]*\)_\1 KB_' | sort -n
pboin
fonte
2
bom para não ter de instalar outra coisa para obter os resultados que eu preciso
Taranaki
16

Se você não possui uma versão recente do GNU coreutils , pode ligar dusem -hobter uma saída classificável e produzir uma saída amigável ao ser humano com um pouco de pós-processamento. Isso tem a vantagem de funcionar, mesmo que sua versão dunão tenha o -hsinalizador.

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 você deseja sufixos SI (ou seja, múltiplos de 1000 em vez de 1024), altere 1024 para 1000 no whilecorpo do loop. (Observe que 1000 na condição é pretendida, para que você obtenha, por exemplo, em 1Mvez de 1000k.)

Se você dutiver a opção de exibir tamanhos em bytes (por exemplo, -bou -B 1- observe que isso pode ter o efeito colateral de contar os tamanhos de arquivo reais em vez de usar o disco), adicione um espaço ao início de s(ou seja s=" kMGTEPYZ";) ou adicione if (x<1000) {return x} else {x/=1024}no início de a humanfunção

A exibição de um dígito decimal para números no intervalo de 1 a 10 é deixada como exercício para o leitor.

Gilles
fonte
Essa foi a solução pronta para uso que eu encontrei para trabalhar no linux e no mac. Muito obrigado!
Brian Graham
9

Se você não possui, sort -hpode fazer o seguinte:

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

Isso obtém a lista du, separa o sufixo e classifica usando isso. Como não há sufixo para <1K, o primeiro sed adiciona um B (para byte). O segundo sed adiciona um delimitador entre o dígito e o sufixo. O terceiro sed converte G em Z para que seja maior que M; se você tiver arquivos terabytes, precisará converter G em Y e T em Z. Finalmente, classificamos pelas duas colunas e substituímos o sufixo G.

Shawn J. Goff
fonte
Esforço impressionante, mas isso não chega nem perto de funcionar para mim.
jvriesem
6

No OS X, você pode instalar os coreutils necessários via Homebrew :

brew install coreutils

Com isso você terá gsort, que inclui o -hparâmetro da linha de comando.

Roland
fonte
4

Este pequeno script Perl faz o truque. Salve-o como duh(ou o que você quiser) e chame-o comduh /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
fonte
4

Como o Mac OS X não tem a -hopção sort, tentei e aprendi sede awkpara uma primeira tentativa:

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

é uma fila longa. Expandido, é:

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; 

}'

Eu tentei no Mac OS X Mavericks, Yosemite, Ubuntu 2014-04 com awksendo o padrão awk(que é nawk, porque ambos awke nawkponto a /usr/bin/mawk) ou ficar de boca aberta, e todos eles trabalharam.

Aqui está uma amostra da saída em um 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

em vez de du -sk *, vi na resposta de @ Stefan onde o total geral também é exibido e sem passar por nenhum ponto de montagem do sistema de arquivos usandodu -skcx *

nopole
fonte
1

Aqui está o que eu uso no Ubuntu 10.04, CentOS 5.5, FreeBSD e Mac OS X.

Peguei emprestada a idéia de www.geekology.co.za/ e earthinfo.org , além dos patos infames de "Linux Server Hacks" de O'Reilly. Ainda estou adaptando-o às minhas necessidades. Ainda está em andamento (como eu estava trabalhando no trem esta manhã.):

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

Aqui está a saída:

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
fonte
Eu acho que você quis dizer du -cks -x *? (com o asterisco)
nopole
O asterisco é redundante nesse uso. De uma chance.
Stefan Lasiewski
quer dizer colocar o primeiro conjunto de código em um arquivo chamado ducks, e, em seguida, chmod a+x duckse depois usar ./duckspara executá-lo? Então, vejo apenas o uso total do disco, no Mac OS X e no Ubuntu 2014-10. Eu também tentei colocar a ducks() { ...}definição em .bashrce, em seguida, usar duckspara executá-lo, ea mesma coisa no Mac OS X, ver apenas o total geral
nopole
1

Enlouqueça com este 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;}'
jaypal singh
fonte
1

Na ausência do GNU sort -h, isso deve funcionar na maioria dos ambientes 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
fonte
0

Este lida com nomes de arquivos com espaço em branco ou apóstrofos e funciona em sistemas que não suportam xargs -dou sort -h:

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

o que resulta em:

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

Isso classificará a saída em ordem decrescente de tamanho:

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

Isso classificará a saída em ordem crescente de tamanho:

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

PS: pode ser usado para classificar por qualquer coluna, mas os valores da coluna devem estar no mesmo formato

user5337995
fonte
1
No. sort -k1rné equivalente sort -rne apenas classifica numericamente com base na sequência inicial de dígitos decimais em cada linha. Ele não entende ponto flutuante, e ele não entende as k, M, G... sufixos. 10.1k seria considerado maior do que 1,23g
Stéphane Chazelas
0

Testado no 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

Isso produzirá todos os tamanhos de diretório de forma recursiva, na parte inferior será o maior diretório em Gigabytes e no menor, em Kilobytes.

Chuguniy
fonte
0

O maior está na parte inferior:

du -sh * | sort -h
Meskan
fonte
0

Comando:

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

Explicação:

  • Listar o tamanho de todos os arquivos / pastas recursivamente no diretório atual em formato legível por humanos

du -ah .

  • Classifique o tamanho legível por humanos que está presente na primeira coluna e mantenha os 50 maiores

sort -k1 -h | tail -n 50

Rohan Ghige
fonte
-1

Para classificar por tamanho em MB

du --block-size=MiB --max-depth=1 path | sort -n
lukmansh
fonte
O usuário deseja obter a saída de du -h(saída legível por humanos) classificada numericamente. Você não está dando uma resposta para isso. Você também pode vincular sua conta do UNIX-SE às outras contas que você possui nos outros sites do SE.
Tonin
-2

Esse script é ainda mais fácil:

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

para OSX

du -h -k  {PATH} | sort -n
Steve Greensides
fonte
não é -kapenas o cancelamento -he, em caso afirmativo, como isso fornece a saída legível por humanos solicitada pelo OP.
Anthon 10/10