Comment triez-vous la sortie par taille?

196

Comment triez-vous du -sh /dir/*par taille? J'ai lu un site qui disait utilisation | sort -nmais ce n'est évidemment pas correct. Voici un exemple qui ne va pas.

[~]# 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
xénoterracide
la source
3
Je savais que j'avais déjà vu ça auparavant . La réponse la plus votée là - bas n'est pas très bonne, mais d' autres sont meilleures .
Gilles
La réponse acceptée a sort -hfonctionné pour moi dans Ubuntu 16.04 LTS en août 2017. Premièrement, je trouve mon lecteur monté par cd /mnt(monté par UUID dans fstab). Ensuite , je ne du >~/dumnt.out puis sort -h ~/dumnt.out >~/dumntsort.outalors je peux faire la queue `~ / dumntsort.out pour voir les plus grands porcs d'espace.
SDsolar

Réponses:

252

Si vous utilisez GNU coreutils (courant dans la plupart des distributions Linux), vous pouvez utiliser

du -sh -- * | sort -h

L' -hoption indique sortque l'entrée est le format lisible par l'homme (nombre avec unité; basé sur 1024, de sorte que 1023 est considéré comme inférieur à 1K, ce qui correspond à ce que fait GNU du -h).

Cette fonctionnalité a été ajoutée à GNU Core Utilities 7.5 en août 2009 .

Remarque:

Si vous utilisez une version antérieure de Mac OSX, vous devez installer coreutils avec brew install coreutils, puis l’utiliser gsortcomme solution de remplacement sort.

Les nouvelles versions de macOS (vérifié sur Mojave) prennent sort -hen charge de manière native.

Shawn J. Goff
la source
27
remarque: ajoutez -rpour trier si vous voulez les plus gros en haut
xenoterracide
9
Sur Mac OS X , vous pouvez installer coreutilsvia brewet ajouter le dossier bin à votre PATHdans votre rc fichier, et -hdevrait être disponible.
Kenorb
Oh, merci pour le rappel. cela signifie que je n'ai pas besoin de la tailcommande pour voir les porcs.
SDsolar
47

Essayez d’utiliser le drapeau -k pour compter 1K blocs au lieu d’être lisibles par l’homme. Ensuite, vous avez une unité commune et pouvez facilement faire un tri numérique.

du -ck | sort -n

Vous n'avez pas explicitement besoin d'unités humaines, mais si vous l'avez fait, il y a plusieurs façons de le faire. Beaucoup semblent utiliser la technique du bloc 1K ci-dessus, puis faire un deuxième appel à du.

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

Si vous voulez voir les unités de base de connaissances ajoutées, utilisez:

du -k | sed -e 's_^\([0-9]*\)_\1 KB_' | sort -n
pboin
la source
2
sympa de ne pas avoir à installer autre chose pour obtenir les résultats dont j'ai besoin
taranaki
16

Si vous ne disposez pas d'une version récente de GNU coreutils , vous pouvez appeler dusans -hobtenir une sortie triable et produire une sortie conviviale avec un peu de post-traitement. Cela a l’avantage de fonctionner même si votre version dun’a pas le -hdrapeau.

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 vous voulez des suffixes SI (c'est-à-dire des multiples de 1000 au lieu de 1024), remplacez 1024 par 1000 dans le whilecorps de la boucle. (Notez que 1000 dans la condition est prévu, de sorte que vous obtenez par exemple 1Mplutôt que 1000k.)

Si vous avez dul'option d'afficher les tailles en octets (par exemple -bou -B 1- notez que cela peut avoir pour effet secondaire de compter les tailles de fichier réelles plutôt que l'utilisation du disque), ajoutez un espace au début de s(c'est-à-dire s=" kMGTEPYZ";) ou ajoutez if (x<1000) {return x} else {x/=1024}au début de la humanfonction.

L'affichage d'un chiffre décimal pour les nombres compris entre 1 et 10 est laissé au lecteur sous forme d'exercice.

Gilles
la source
C'est la solution prête à l'emploi que j'ai trouvée qui fonctionne à la fois sous linux et mac. Merci beaucoup!
Brian Graham
9

Si vous n'en avez pas, sort -hvous pouvez le faire:

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

Ceci obtient la liste du, sépare le suffixe et trie en utilisant cela. Comme il n'y a pas de suffixe pour <1K, le premier sed ajoute un B (pour byte). Le second sed ajoute un séparateur entre le chiffre et le suffixe. Le troisième sed convertit G en Z de sorte qu'il soit plus grand que M; si vous avez des fichiers en téraoctets, vous devrez convertir G en Y et T en Z. Enfin, nous trions en fonction des deux colonnes, puis nous remplaçons le suffixe G.

Shawn J. Goff
la source
Effort impressionnant, mais cela ne me permet pas de travailler.
jvriesem
6

Sous OS X, vous pouvez installer les coreutils nécessaires via Homebrew :

brew install coreutils

Avec cela, vous aurez gsort, qui comprend le -hparamètre de ligne de commande.

Roland
la source
4

Ce petit script Perl fait l'affaire. Enregistrez-le sous duh(ou ce que vous voulez) et appelez-le avecduh /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
la source
4

Comme Mac OS X n’a pas d’ -hoption pour sort, j’ai donc essayé et appris sedet awkpour une première tentative:

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

c'est une longue file. Développé, il est:

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; 

}'

Je l' ai essayé sur Mac OS X Mavericks, Yosemite, Ubuntu 2014-04 avec awkêtre la valeur par défaut awk( ce qui est nawk, parce que les deux awket le nawkpoint à /usr/bin/mawk) ou reluquer, et ils ont tous travaillé.

Voici un exemple de la sortie sur un 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

au lieu de du -sk *, j’ai vu dans la réponse de @ Stefan où le total général est également affiché, et sans traverser aucun point de montage du système de fichiers, en utilisantdu -skcx *

nopole
la source
1

Voici ce que j'utilise sur Ubuntu 10.04, CentOS 5.5, FreeBSD et Mac OS X.

J'ai emprunté l'idée de www.geekology.co.za/ et earthinfo.org , ainsi que des canards infâmes de "Linux Server Hacks" de O'Reilly. Je l'adapte toujours à mes besoins. C'est toujours un travail en cours (comme dans, je travaillais sur ceci dans le train ce matin.):

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

Voici la sortie:

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
la source
Je pense que tu voulais dire du -cks -x *? (avec l'astérisque)
nopole
L'astérisque est redondant dans cet usage. Essaie.
Stefan Lasiewski
voulez-vous dire mettre le premier ensemble de code dans un fichier appelé ducks, chmod a+x duckspuis l'utiliser ./duckspour l'exécuter? Ensuite, je ne vois que l'utilisation totale du disque, à la fois sur Mac OS X et sur Ubuntu 2014-10. J'ai également essayé de mettre la ducks() { ...}définition dans .bashrc, puis de l'utiliser duckspour l'exécuter, et la même chose sur Mac OS X, seulement voir le grand total
nopole
1

Deviens fou avec ce 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
la source
1

En l'absence de GNU sort -h, cela devrait fonctionner dans la plupart des environnements 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
la source
0

Celui-ci gère les noms de fichiers avec des espaces ou des apostrophes, et fonctionne sur des systèmes qui ne prennent pas en charge xargs -dou sort -h:

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

qui se traduit par:

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

Cela triera la sortie par ordre décroissant de taille:

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

Cela va trier la sortie par ordre croissant de taille:

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

PS: cela peut être utilisé pour trier par n'importe quelle colonne mais les valeurs de colonne doivent être au même format

utilisateur5337995
la source
1
No. sort -k1rnest équivalent à sort -rnet trie simplement numériquement sur la base de la séquence initiale de chiffres décimaux sur chaque ligne. Il ne comprend pas à virgule flottante, et il ne comprend pas les k, M, G... suffixes. 10.1k serait considéré comme supérieur à 1.23G
Stéphane Chazelas
0

Testé sur 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

Cela va générer toutes les tailles de répertoires de manière récursive, en bas le répertoire le plus grand en gigaoctets et le plus petit en kilo-octets.

Chuguniy
la source
0

Le plus grand est en bas:

du -sh * | sort -h
Meskan
la source
0

Commander:

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

Explication:

  • Taille de la liste de tous les fichiers / dossiers de manière récursive dans le répertoire en cours sous une forme lisible par l'homme

du -ah .

  • Triez la taille lisible par l’homme qui est présente dans la première colonne et conservez la plus grande taille.

sort -k1 -h | tail -n 50

Rohan Ghige
la source
-1

Pour trier par taille en Mo

du --block-size=MiB --max-depth=1 path | sort -n
lukmansh
la source
L'utilisateur veut obtenir la sortie de du -h(sortie lisible par l'homme) triée numériquement. Vous ne répondez pas à cela. Vous pouvez également souhaiter lier votre compte UNIX-SE aux autres comptes que vous avez sur les autres sites SE.
Tonin
-2

Ce script est encore plus simple:

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

pour OSX

du -h -k  {PATH} | sort -n
Steve Greensides
la source
l’ -kannulation n’est pas juste -het si oui comment cela fournit-il la sortie lisible par l’homme demandée par le PO.
Anthon