1489 votes

Comment puis-je trier la sortie de du -h par taille ?

J'ai besoin d'obtenir une liste de sortie du lisible par l'homme.

Cependant, du n'a pas d'option "trier par taille", et le tuyautage à sort ne fonctionne pas avec l'indicateur de lisibilité humaine.

Par exemple, en courant :

du | sort -n -r 

Produit une utilisation du disque triée par taille (en ordre décroissant) :

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

Cependant, en l'exécutant avec l'indicateur de lisibilité humaine, le tri ne se fait pas correctement :

du -h | sort -n -r

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

Quelqu'un connaît-il un moyen de trier du -h par taille ?

0 votes

Voici une question très proche : serverfault.com/q/737537/35034

0 votes

Vous avez vu celui-ci ? unix.stackexchange.com/questions/4681/ Il s'agit d'un quasi-duplicata et il vaut de l'or. Vous faites une recherche normale du mais ajoutez le -h à l'option sort commande. Vous pouvez ajouter -rh afin que les plus grands soient les premiers dans le fichier, sinon vous devez tail pour voir les porcs de l'espace.

0 votes

Voir aussi superuser.com/questions/300606/ pour une alternative plus conviviale ( ncdu ).

25voto

Paul Wicks Points 13205

D'après ce que je vois, vous avez trois options :

  1. Alter du pour trier avant l'affichage.
  2. Alter sort pour supporter les tailles humaines pour le tri numérique.
  3. Post-traiter la sortie du tri pour rendre la sortie de base lisible par l'homme.

Vous pouvez également faire du -k et vivre avec des tailles en KiB.

Pour l'option 3, vous pourriez utiliser le script suivant :

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

24voto

littlebyte Points 258

J'ai eu ce problème également et j'utilise actuellement une solution de contournement :

du -scBM | sort -n

Cela ne produira pas de valeurs mises à l'échelle, mais toujours la taille en mégaoctets. Ce n'est pas parfait, mais pour moi c'est mieux que rien (ou que l'affichage de la taille en octets).

0 votes

J'aime le commutateur -BM, qui est fondamentalement le même que -m, mais il a l'avantage d'afficher la taille et le M postfixé à celle-ci, ainsi vous obtenez 10M qui est beaucoup plus clair que juste 10 :)

0 votes

C'est la solution la plus simple que j'ai vue jusqu'à présent sur cette page, merci !

21voto

Adam Bellaire Points 1170

Trouvé cette affectation ailleurs. Par conséquent, ce Shell ShellscriptShell fera ce que vous voulez sans faire appel à du sur tout deux fois. Il utilise awk pour convertir les octets bruts en un format lisible par l'homme. Bien sûr, le formatage est légèrement différent (tout est imprimé avec une précision d'une décimale).

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

Je l'utilise dans mon .vim rendement du répertoire :

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

(J'espère que 3,6M de schémas de couleurs n'est pas excessif).

3 votes

J'ai aussi une réponse en Perl, mais je pense que les gens risquent de me détester : du -B1 | sort -nr | perl -e '%h=(0=>b,1=>K,2=>M,3=>G);for(<>){($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;}'

0 votes

Même si la réponse de Perl donne en fait un formatage beaucoup plus proche de du. Même si l'arrondi est incorrect... Il semble que du donne toujours ceil() plutôt que round().

0 votes

Hey, pourquoi j'ai utilisé un dièse là ? J'aurais dû utiliser un tableau... cerveau du matin. ronchonnement ....

21voto

jason saldo Points 5036

Cette version utilise awk pour créer des colonnes supplémentaires pour les clés de tri. Il appelle seulement du une fois. La sortie devrait ressembler exactement à du .

Je l'ai divisé en plusieurs lignes, mais il peut être recombiné en une seule ligne.

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

Explication :

  • BEGIN - créer une chaîne de caractères à indexer pour substituer 1, 2, 3 pour K, M, G pour le regroupement par unités, s'il n'y a pas d'unité (la taille est inférieure à 1K), alors il n'y a pas de correspondance et un zéro est retourné (parfait !).
  • imprime les nouveaux champs - unité, valeur (pour que le tri alpha fonctionne correctement, il y a un décalage de zéro et une longueur fixe) et la ligne originale.
  • indexe le dernier caractère du champ de taille
  • sortez la partie numérique de la taille
  • trier les résultats, éliminer les colonnes supplémentaires

Essayez-le sans le cut pour voir ce qu'il fait.

Voici une version qui fait le tri dans le script de AWK et qui n'a pas besoin de 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 votes

Merci ! c'est le premier exemple qui fonctionne pour moi sous OS X 10.6 sans compter les scripts perl/phython-scripts. et merci encore pour la bonne explication. toujours agréable d'apprendre quelque chose de nouveau. awk est vraiment un outil puissant.

0 votes

Merci beaucoup pour ça. J'ai changé le du en du -sh * pour afficher uniquement les fichiers et répertoires immédiats sans descente récursive.

20voto

nex3 Points 4309

Voici un exemple qui montre les répertoires sous une forme résumée plus compacte. Il gère les espaces dans les noms de répertoires/films.

% du -s * | sort -rn | cut -f2- | xargs -d "\n" du -sh

53G  projects
21G  Desktop
7.2G VirtualBox VMs
3.7G db
3.3G SparkleShare
2.2G Dropbox
272M apps
47M  incoming
14M  bin
5.7M rpmbuild
68K  vimdir.tgz

1 votes

Les utilisateurs de macOS/OSX doivent être avertis que la version mac de xargs ne supporte pas l'option -d, et si vous l'omettez, tous les répertoires qui contiennent un espace seront analysés séparément, ce qui bien sûr échoue.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X