¿Cómo se clasifica la salida por tamaño?

196

¿Cómo se clasifica du -sh /dir/*por tamaño? Leí un sitio que decía uso, | sort -npero obviamente eso no está bien. Aquí hay un ejemplo que está mal.

[~]# 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
fuente
3
Sabía que había visto esto antes . La respuesta más votada allí no es muy buena, pero otras son mejores .
Gilles
La respuesta aceptada sort -hfuncionó para mí en Ubuntu 16.04 LTS en agosto de 2017. Primero encuentro mi unidad montada por cd /mnt(montada por UUID en fstab). Luego lo hago du >~/dumnt.out y sort -h ~/dumnt.out >~/dumntsort.outluego puedo hacer `tail ~ / dumntsort.out para ver los cerdos espaciales más grandes.
SDsolar

Respuestas:

252

Si tiene coreutils de GNU (común en la mayoría de las distribuciones de Linux), puede usar

du -sh -- * | sort -h

La -hopción indica sortque la entrada es el formato legible para humanos (número con unidad; basado en 1024, de modo que 1023 se considera menor que 1K, lo que coincide con lo que du -hhace GNU ).

Esta característica se agregó a GNU Core Utilities 7.5 en agosto de 2009 .

Nota:

Si está utilizando una versión anterior de Mac OSX, debe instalar coreutils con brew install coreutils, luego usar gsortcomo reemplazo directo de sort.

Las versiones más recientes de macOS (verificadas en Mojave) son compatibles de sort -hforma nativa.

Shawn J. Goff
fuente
27
nota: agregue -rpara ordenar, si desea los más grandes en la parte superior
xenoterracide
99
En OSX puede instalar coreutilsa través brewy agregar la carpeta bin a la PATHen su rc archivo y -hdebe estar disponible.
kenorb
Oh, gracias por el recordatorio. eso significa que no necesito el tailcomando para ver a los cerdos.
SDsolar
47

Intente usar el indicador -k para contar bloques de 1K en lugar de usar legibles para humanos. Entonces, tiene una unidad común y puede hacer fácilmente una ordenación numérica.

du -ck | sort -n

No necesitas explícitamente unidades humanas, pero si lo hiciste, entonces hay muchas maneras de hacerlo. Muchos parecen usar la técnica de bloqueo 1K anterior, y luego hacen una segunda llamada a du.

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

Si desea ver las unidades KB agregadas, use:

du -k | sed -e 's_^\([0-9]*\)_\1 KB_' | sort -n
pboin
fuente
2
agradable no tener que instalar algo más para obtener los resultados que necesito
taranaki
16

Si no tiene una versión reciente de los coreutils de GNU , puede llamar dusin -hobtener una salida ordenable y producir una salida amigable para los humanos con un poco de posprocesamiento. Esto tiene la ventaja de funcionar incluso si su versión de duno tiene la -hbandera.

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

Si desea sufijos SI (es decir, múltiplos de 1000 en lugar de 1024), cambie 1024 a 1000 en el whilecuerpo del bucle. (Tenga en cuenta que se pretende 1000 en la condición, de modo que obtenga, por ejemplo, en 1Mlugar de 1000k).

Si dutiene una opción para mostrar tamaños en bytes (por ejemplo, -bo -B 1- tenga en cuenta que esto puede tener el efecto secundario de contar los tamaños de archivo reales en lugar del uso del disco), agregue un espacio al comienzo de s(es decir s=" kMGTEPYZ";), o agregue if (x<1000) {return x} else {x/=1024}al comienzo de La humanfunción.

Mostrar un dígito decimal para los números en el rango 1–10 se deja como ejercicio para el lector.

Gilles
fuente
Esta ha sido la solución lista para usar que he encontrado que funciona tanto en Linux como en Mac. ¡Muchas gracias!
Brian Graham el
9

Si no sort -htienes puedes hacer esto:

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

Esto obtiene la lista du, separa el sufijo y se ordena usando eso. Como no hay sufijo para <1K, el primer sed agrega una B (por byte). El segundo sed agrega un delimitador entre el dígito y el sufijo. El tercer sed convierte G a Z para que sea más grande que M; Si tiene archivos de terabytes, tendrá que convertir G a Y y T a Z. Finalmente, ordenamos por las dos columnas, luego reemplazamos el sufijo G.

Shawn J. Goff
fuente
Esfuerzo impresionante, pero esto no se acerca a trabajar para mí.
jvriesem
6

En OS X, puede instalar los coreutils necesarios a través de Homebrew :

brew install coreutils

Con esto tendrás gsort, que incluye el -hparámetro de línea de comando.

Roland
fuente
4

Este pequeño script de Perl hace el truco. Guárdalo como duh(o como quieras) y llámalo 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;
ddeimeke
fuente
4

Como Mac OS X no tiene la -hopción sort, lo intenté y aprendí sedy awkpara un primer intento:

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 una larga cola. Ampliado, 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; 

}'

Lo he probado en Mac OS X Mavericks, Yosemite, Ubuntu 2014-04 con awkser el valor por defecto awk(que es nawk, porque ambos awky nawkel punto a /usr/bin/mawk) o curiosear, y todos ellos trabajaba.

Aquí hay una muestra de la salida en una 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

en lugar de du -sk *, vi en la respuesta de @ Stefan donde también se muestra el gran total, y sin atravesar ningún punto de montaje del sistema de archivos, usandodu -skcx *

nopole
fuente
1

Esto es lo que uso en Ubuntu 10.04, CentOS 5.5, FreeBSD y Mac OS X.

Me tomó la idea de www.geekology.co.za/ y earthinfo.org , así como los famosos patos de "Servidor Linux Hacks" de O'Reilly. Todavía lo estoy adaptando a mis necesidades. Esto todavía es un trabajo en progreso (como en, estaba trabajando en esto en el tren esta mañana):

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

Aquí está la salida:

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
fuente
Creo que quisiste decir du -cks -x *? (con el asterisco)
nopole
El asterisco es redundante en este uso. Darle una oportunidad.
Stefan Lasiewski
¿te refieres a poner el primer conjunto de código en un archivo llamado ducks, chmod a+x ducksy luego usarlo ./duckspara ejecutarlo? Entonces solo veo el uso total del disco, tanto en Mac OS X como en Ubuntu 2014-10. También intenté poner la ducks() { ...}definición .bashrcy luego usarla duckspara ejecutarla, y lo mismo en Mac OS X, solo veo el gran total
nopole
1

Vuélvete loco con 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
fuente
1

En ausencia de GNU sort -h, esto debería funcionar en la mayoría de los entornos 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
fuente
0

Este maneja nombres de archivos con espacios en blanco o apóstrofes, y funciona en sistemas que no admiten xargs -do sort -h:

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

lo que resulta en:

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

Esto ordenará la salida en orden decreciente de tamaño:

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

Esto ordenará la salida en orden creciente de tamaño:

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

PD: esto se puede usar para ordenar por cualquier columna, pero los valores de esa columna deben estar en el mismo formato

usuario5337995
fuente
1
No. sort -k1rnes equivalente sort -rny se ordena numéricamente según la secuencia inicial de dígitos decimales en cada línea. No entiende de punto flotante, y que no entiende los k, M, G... sufijos. 10.1k se consideraría mayor que 1.23G
Stéphane Chazelas
0

Probado en 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

Esto generará todos los tamaños de directorio de forma recursiva, en la parte inferior será el directorio más grande en Gigabytes y en la parte superior más pequeño en Kilobytes.

Chuguniy
fuente
0

El más grande está en la parte inferior:

du -sh * | sort -h
Meskan
fuente
0

Mando:

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

Explicación:

  • Tamaño de la lista de todos los archivos / carpetas de forma recursiva en el directorio actual en forma legible por humanos

du -ah .

  • Clasifique el tamaño legible por humanos que está presente en la primera columna y mantenga el 50 más grande

sort -k1 -h | tail -n 50

Rohan Ghige
fuente
-1

Para ordenar por tamaño en MB

du --block-size=MiB --max-depth=1 path | sort -n
lukmansh
fuente
El usuario quiere obtener la salida de du -h(salida legible por humanos) ordenada numéricamente. No estás dando una respuesta a eso. También puede vincular su cuenta UNIX-SE con las otras cuentas que tiene en los otros sitios SE.
Tonin
-2

Este script es aún más fácil:

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

para OSX

du -h -k  {PATH} | sort -n
Steve Greensides
fuente
no es -ksolo la cancelación -hy, de ser así, ¿cómo proporciona esto la salida legible por humanos solicitada por el OP?
Anthon