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


Necesito obtener una lista de salida du legible para humanos.

Sin embargo, du no tiene una opción de "ordenar por tamaño" y canalizar a sort No funciona con la bandera legible por humanos.

Por ejemplo, ejecutando:

du | sort -n -r 

Produce un uso de disco ordenado por tamaño (descendente):

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

Sin embargo, ejecutarlo con el indicador legible, no se ordena correctamente:

du -h | sort -n -r

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

¿Alguien sabe de una manera de ordenar du -h  ¿por tamaño?


830
2018-02-25 13:42


origen


Jeh ... Es gracioso que lo preguntes, ya que esto me ha estado molestando por ... al menos más de un año. La semana pasada descargué el código a los coreutils de GNU (de los que forma parte), y eché un vistazo, pero decidí que me tomaría un poco más de tiempo de lo que tenía en mis manos parchear ... ¿Alguien? :) - unwind
Aquí hay una pregunta muy relacionada: serverfault.com/q/737537/35034 - cregox
¿Has visto este? unix.stackexchange.com/questions/4681/…  Es un duplicado cercano y vale oro. Haces un normal du pero agrega la -h a la sort mando. Puedes añadir -rh así que los más grandes son los primeros en el archivo, de lo contrario necesitas tail Para ver los cerdos espaciales. - SDsolar
No esperaba que tal pregunta fuera tan popular cuando busqué en Google. - Mateen Ulhaq


Respuestas:


A partir de Coreutils GNU 7.5 lanzado en agosto de 2009, sort permite un -h parámetro, que permite sufijos numéricos del tipo producido por du -h:

du -hs * | sort -h

Si está utilizando una ordenación que no es compatible -h, puedes instalar GNU Coreutils. P.ej. en un Mac OS X antiguo:

brew install coreutils
du -hs * | gsort -h

Desde sort manual:

-h, --human-numeric-sort compare human readable numbers (e.g., 2K 1G)


1152
2017-07-01 12:29



La sección correspondiente del manual: gnu.org/software/coreutils/manual/… - wodow
Fácil de instalar en OS X con homebrew - brew install coreutils. - Richard Poirier
Bueno uno Yo personalmente siempre lo hice du -BM | sort -nr como solución alternativa: es lo suficientemente legible para los humanos, y está ordenado, si alguien está atascado con los núcleos básicos más antiguos. - chutz
Si lo usa en OSX a través de Homebrew, tenga en cuenta que ahora necesitará usar gsort en lugar de ordenar: du -hs * | gsort -h - Brian Cline
@PaulDraper, du -BM imprime todo en megabytes, por lo que un archivo que es 168K en realidad se mostraría como 0M. A menos que haya alguna otra discrepancia en la versión, no la conozco. Mi version de du Solo muestra valores de megabyte enteros. - chutz


du | sort -nr | cut -f2- | xargs du -hs

82
2018-02-25 13:52



Y va a hacer una gran cantidad de conteo duplicado. - Douglas Leeder
Primero hace el du normal, luego, para cada entrada, vuelve a calcular el tamaño para imprimirlo en forma legible. - Douglas Leeder
@Douglas Leeder: tiene razón para el conteo duplicado, pero cree que el segundo du no se inicia desde la caché fría (gracias al sistema operativo) @ hasen j: xargs es un comando muy útil, divide su stdin y lo alimenta como argumentos al comando dado - cadrian
Chris's es realmente superior, ya que funciona con rutas que contienen espacios en blanco. Lanzar un voto a tu manera, amigo. - rbright
Feo, pero multiplataforma :). - voretaq7


@Douglas Leeder, una respuesta más: Ordene la salida legible por 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)}<>;'

Dividir en dos líneas para adaptarse a la pantalla. Puedes usarlo de esta manera o convertirlo en una línea, funcionará de cualquier manera.

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

59
2018-02-25 21:04



Tu versión corta sale en stderr debido a la die ¿Puedes cambiarlo para que salga en stdout? - Dennis Williamson
Cambiar el die a un print y irá a stdout. Son solo dos personajes más. - Adam Bellaire
funciona en ubuntu! - marinara
impresionante perl hackistica - nandoP
El resultado está en orden inverso :( - RSFalcon7


Hay una herramienta inmensamente útil que uso llamada ncdu que está diseñado para encontrar esas carpetas y archivos molestos de alto uso de disco y eliminarlos. Es basado en la consola, rápido y ligero, y tiene paquetes en todas las principales distribuciones.


50
2018-02-25 20:39



Muy bonito ... Me pregunto si los resultados se podrían enviar a la salida estándar ... Soy tan vago que no puedo leer el manual. - ojblass
gt5 está en la misma vena; su característica asesina está mostrando crecimiento. - Tobu
¡Eso es realmente genial! Y mucho más rápido que andar con du, si solo quieres identificar los directorios grandes. - BurninLeo


du -k * | sort -nr | cut -f2 | xargs -d '\n' du -sh

43
2018-02-25 14:01



justo lo que estaba buscando gracias - Edward Tanguay
No se puede usar con du -k --total, da error al final du: cannot access 'total': No such file or directory - laggingreflex
Me gusta esta una más cualquier otra respuesta. ¿Cómo irías para mostrar solo los primeros 50 resultados? - Mauro
@Mauro - solo canaliza el resultado a head añadiendo `| cabeza -50` al final. - Samuel Lelièvre


Por lo que puedo ver tienes tres opciones:

  1. Alterar du para ordenar antes de mostrar
  2. Alterar sort Para soportar tamaños humanos para ordenación numérica.
  3. Posteriormente, procese la salida del ordenamiento para cambiar la salida básica a legible para humanos.

Tambien podrias hacer du -k y vivir con tallas en KiB.

Para la opción 3 podrías usar 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

20
2018-02-25 13:53





También he tenido ese problema y actualmente estoy usando una solución alternativa:

du -scBM | sort -n

Esto no producirá valores escalados, pero siempre producirá el tamaño en megabytes. Eso es menos que perfecto, pero para mí es mejor que nada (o mostrar el tamaño en bytes).


19
2018-02-25 13:56



Me gusta el interruptor -BM, que es básicamente el mismo que el -m, pero tiene la ventaja de mostrar el tamaño y la M posfijados, así que obtienes 10M, que es mucho más claro que solo 10 :) - Tom Feiner
Esta es la solución más simple que he visto hasta ahora en esta página, ¡gracias! - Jeff Olson


Encontró esta publicación en otra parte. Por lo tanto, este script de shell hará lo que quieras sin llamar du en todo dos veces Usa awk para convertir los bytes en bruto a un formato legible por humanos. Por supuesto, el formato es ligeramente diferente (todo se imprime con una precisión de un decimal).

#/bin/bash
du -B1 | sort -nr  |awk '{sum=$1;
hum[1024**3]="G";hum[1024**2]="M";hum[1024]="K";
for (x=1024**3; x>=1024; x/=1024){
        if (sum>=x) { printf "%.1f%s\t\t",sum/x,hum[x];print $2;break
}}}'

Corriendo esto en mi .vim directorio de rendimientos:

4.4M            .
3.6M            ./colors
372.0K          ./plugin
128.0K          ./autoload
100.0K          ./syntax
100.0K          ./doc

(Espero que 3.6M de esquemas de color no sea excesivo.)


18
2018-02-25 14:09



También tengo una respuesta de Perl, pero creo que podría hacer que la gente me odie: du -B1 | ordenar -nr | perl -e '% h = (0 => b, 1 => K, 2 => M, 3 => G); para (<>) {($ s, @ f) = split / \ s + /; $ e = 3; $ e-- while (1024 ** $ e> $ s); $ v = ($ s / (1024 ** $ e)); printf "% -8s% s \ n", sprintf ($ v> = 100? "% d% s": "% .1f% s", $ s / (1024 ** $ e), $ h {$ e}), @ f;} ' - Adam Bellaire
A pesar de que la respuesta de Perl en realidad da su formato mucho más cerca de du. Aunque el redondeo está desactivado ... Parece que du siempre da ceil () en lugar de round () - Adam Bellaire
Oye, ¿por qué usé un hash allí? Debería haber sido una matriz ... mañana-cerebro queja.... - Adam Bellaire
Agregó una mejor solución de Perl como otra respuesta. - Adam Bellaire
Ambas versiones fallan cuando los nombres de archivo contienen espacios - Vi.


Esta versión usa awk para crear columnas adicionales para las claves de clasificación. Solo llama du una vez. La salida debe verse exactamente como du.

Lo he dividido en varias líneas, pero se puede volver a combinar 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:

  • COMIENZO: cree una cadena para indexar sustituyendo 1, 2, 3 por K, M, G para agrupar por unidades, si no hay una unidad (el tamaño es menor que 1K), entonces no hay coincidencia y se devuelve un cero (¡perfecto! )
  • imprima los nuevos campos - unidad, valor (para hacer que la ordenación alfa funcione correctamente, no tiene relleno, es de longitud fija) y la línea original
  • indexar el último carácter del campo de tamaño
  • saque la parte numérica del tamaño
  • ordenar los resultados, descartar las columnas adicionales

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

Aquí hay una versión que hace la clasificación dentro del script AWK 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]]}'

14
2017-09-04 17:06



¡gracias! Este es el primer ejemplo que funciona para mí en OS X 10.6 sin contar los scripts de perl / phython. Y gracias de nuevo por la buena explicación. Siempre es bueno aprender algo nuevo. awk seguro es una herramienta poderosa. - Wolf
Muchas gracias por eso. Cambié el du a du -sh * para mostrar sólo los archivos y directorios inmediatos sin descenso recursivo. - HankCa