1247 votos

¿Cómo puedo ordenar la salida de du -h por tamaño?

Necesito obtener una lista de salida du legible para el ser humano.

Sin embargo, du no tiene una opción de "ordenar por tamaño", y la canalización a "ordenar" no funciona con la flag de lectura humana.

Por ejemplo, corriendo:

du | sort -n -r

Muestra un uso del disco ordenado por tamaño (descendente):

du |sort -n -r
65108   .
61508   ./dir3
2056    ./dir4
1032    ./dir1
508     ./dir2

Sin embargo, si se ejecuta con la flag de lectura humana, no se clasifica correctamente:

du -h | sort -n -r

508K    ./dir2
64M     .
61M     ./dir3
2.1M    ./dir4
1.1M    ./dir1

¿Alguien conoce una forma de ordenar du -h por tamaño?

0 votos

Esta es una pregunta muy relacionada: serverfault.com/q/737537/35034

0 votos

¿Has visto este? unix.stackexchange.com/questions/4681/ Es casi un duplicado y vale oro. Usted hace una normal du pero añade la -h al sort de la orden. Puede añadir -rh para que los más grandes estén primero en el archivo, de lo contrario se necesita tail para ver los cerdos del espacio.

0 votos

Ver también superuser.com/questions/300606/ para una alternativa más amigable ( ncdu ).

1765voto

ptman Puntos 8492

Utilice GNU coreutils >= 7.5 :

du -hs * | sort -h

4 votos

La sección correspondiente del manual: gnu.org/software/coreutils/manual/

32 votos

Fácil de instalar en OS X con homebrew -- brew install coreutils.

1 votos

Vaya, gracias. Mucho mejor, gracias a mi "evergreen". du -sk * | sort -n

100voto

Helephant Puntos 4085
du | sort -nr | cut -f2- | xargs du -hs

58 votos

Y hará una gran cantidad de conteo de duplicados.

0 votos

¿ayudaría si explica por qué funciona?

1 votos

Primero hace el du normal - luego para cada entrada recalcula el tamaño sólo para imprimirlo en forma legible.

68voto

Adam Bellaire Puntos 495

@Douglas Leeder, una respuesta más: Ordena la salida legible para humanos de du -h usando otra herramienta. ¡Como Perl!

du -h | perl -e 'sub h{%h=(K=>10,M=>20,G=>30);($n,$u)=shift=~/([0-9.]+)(\D)/;
return $n*2**$h{$u}}print sort{h($b)<=>h($a)}<>;'

Se divide en dos líneas para que se ajuste a la pantalla. Puedes usarlo de esta manera o hacerlo de una sola línea, funcionará de cualquier manera.

La salida:

4.5M    .
3.7M    ./colors
372K    ./plugin
128K    ./autoload
100K    ./doc
100K    ./syntax

EDITAR: Después de unas cuantas rondas de golf en PerlMonks El resultado final es el siguiente:

perl -e'%h=map{/.\s/;99**(ord$&&7)-$`,$_}`du -h`;die@h{sort%h}'

2 votos

Sus salidas en versión corta en stderr debido a la die ¿puede cambiarlo para que salga en stdout ?

2 votos

Cambiar el die a un print y pasará a stdout . Son sólo dos personajes más.

0 votos

¡funciona en ubuntu!

24voto

Paul Wicks Puntos 13205

Por lo que veo, tienes tres opciones:

  1. Alter du para ordenar antes de mostrar.
  2. Alter sort para apoyar los tamaños humanos para la clasificación numérica.
  3. Post-procesar la salida de la clasificación para cambiar la salida básica a legible para el ser humano.

También puede hacer du -k y vivir con tamaños en KiB.

Para la opción 3 podrías utilizar el siguiente script:

#!/usr/bin/env python

import sys
import re

sizeRe = re.compile(r"^(\d+)(.*)$")

for line in sys.stdin.readlines():
    mo = sizeRe.match(line)
    if mo:
        size = int(mo.group(1))
        if size < 1024:
            size = str(size)+"K"
        elif size < 1024 ** 2:
            size = str(size/1024)+"M"
        else:
            size = str(size/(1024 ** 2))+"G"

        print "%s%s"%(size,mo.group(2))
    else:
        print line

20voto

jason saldo Puntos 5036

Esta versión utiliza awk para crear columnas adicionales para las claves de clasificación. Sólo llama a du una vez. La salida debe ser exactamente como du .

Lo he dividido en varias líneas, pero se puede recombinar en una sola línea.

du -h |
  awk '{printf "%s %08.2f\t%s\n", 
    index("KMG", substr($1, length($1))),
    substr($1, 0, length($1)-1), $0}' |
  sort -r | cut -f2,3

Explicación:

  • BEGIN - crea una cadena para indexar para sustituir 1, 2, 3 por K, M, G para agrupar por unidades, si no hay unidad (el tamaño es inferior a 1K), entonces no hay coincidencia y se devuelve un cero (¡perfecto!)
  • imprime los nuevos campos - unidad, valor (para que la ordenación alfa funcione correctamente se rellena con cero, de longitud fija) y la línea original
  • indexar el último carácter del campo de tamaño
  • sacar la parte numérica del tamaño
  • ordenar los resultados, descartar las columnas sobrantes

Pruébalo sin el cut para ver lo que está haciendo.

Aquí hay una versión que hace la clasificación dentro del AWK script y no necesita cut :

du -h |
   awk '{idx = sprintf("%s %08.2f %s", 
         index("KMG", substr($1, length($1))),
         substr($1, 0, length($1)-1), $0);
         lines[idx] = $0}
    END {c = asorti(lines, sorted);
         for (i = c; i >= 1; i--)
           print lines[sorted[i]]}'

0 votos

gracias! este es el primer ejemplo que me funciona en OS X 10.6 sin contar los perl/phython-scripts. y gracias de nuevo por la buena explicación. siempre es bueno aprender algo nuevo. awk seguro que es una herramienta poderosa.

0 votos

Gracias por eso. He cambiado el du por du -sh * para mostrar sólo los archivos y directorios inmediatos, sin descenso recursivo.

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: