web-dev-qa-db-fra.com

Comment triez-vous la sortie par taille?

Comment triez-vous du -sh /dir/* par taille? J'ai lu un site qui disait utilisation | sort -n mais ce n'est évidemment pas juste. 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
209
xenoterracide

Si vous avez GNU coreutils (commun dans la plupart des distributions Linux), vous pouvez utiliser

du -sh -- * | sort -h

Le -h option indique à sort que l'entrée est au format lisible par l'homme (nombre avec unité; basé sur 1024 pour que 1023 soit considéré comme inférieur à 1K, ce qui correspond à ce qui est GNU du -h Est-ce que).

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

Remarque:

Si vous utilisez une ancienne version de Mac OSX, vous devez installer coreutils avec brew install coreutils , Puis utilisez gsort comme remplacement direct de sort.

Les nouvelles versions de macOS (vérifiées sur Mojave) prennent en charge sort -h nativement.

268
Shawn J. Goff

Essayez d'utiliser l'indicateur -k pour compter les blocs de 1 000 au lieu d'utiliser un format lisible par l'homme. Ensuite, vous avez une unité commune et pouvez facilement effectuer un tri numérique.

du -ck | sort -n

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

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

Si vous souhaitez voir les unités KB ajoutées, utilisez:

du -k | sed -e 's_^\([0-9]*\)_\1 KB_' | sort -n
49
pboin

Si vous n'avez pas version récente de GNU coreutils , vous pouvez appeler du sans -h Pour obtenir 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 de du n'a pas l'indicateur -h.

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 corps de la boucle while. (Notez que 1000 dans la condition est prévu, de sorte que vous obtenez par exemple 1M Plutôt que 1000k.)

Si votre du a une option pour afficher les tailles en octets (par exemple -b Ou -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 fonction human.

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

Si vous n'avez pas sort -h tu peux 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. Puisqu'il n'y a pas de suffixe pour <1K, le premier sed ajoute un B (pour octet). Le deuxième sed ajoute un délimiteur entre le chiffre et le suffixe. Le troisième sed convertit G en Z pour qu'il soit plus grand que M; si vous avez des fichiers de téraoctets, vous devrez convertir G en Y et T en Z. Enfin, nous trions par les deux colonnes, puis nous remplaçons le suffixe G.

9
Shawn J. Goff

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

brew install coreutils

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

6
Roland

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

Étant donné que Mac OS X n'a ​​pas le -h option pour sort, j'ai donc essayé et appris sed et awk pour 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é, c'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 étant la valeur par défaut awk (qui est nawk, car à la fois awk et nawk pointez sur /usr/bin/mawk) ou gawk, 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 grand total est également affiché, et sans traverser aucun point de montage du système de fichiers, en utilisant du -skcx *

4
nonopolarity

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

J'ai emprunté l'idée à www.geekology.co.za/ et earthinfo.org , ainsi que l'infâme canards à "Linux Server Hacks "par O'Reilly. Je l'adapte toujours à mes besoins. C'est toujours un travail en cours (comme dans, je travaillais là-dessus 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:~ $
1
Stefan Lasiewski

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 }'
1
friedl.otto

Devenez 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;}'
1
jaypal singh

Commande:

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

Explication:

  • Liste la taille de tous les fichiers/dossiers de manière récursive dans le répertoire actuel sous une forme lisible par l'homme

du -ah .

  • Trier la taille lisible par l'homme qui est présente dans la première colonne et conserver la plus grande 50

sort -k1 -h | tail -n 50

0
Rohan Ghige

Le plus gros est en bas:

du -sh * | sort -h
0
Meskan

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 -d ou sort -h:

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

ce qui se traduit par:

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

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

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

Cela triera 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 des colonnes doivent être au même format

0
user5337995

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 affichera toutes les tailles de répertoire de manière récursive, en bas sera le plus grand répertoire en gigaoctets et en haut le plus petit en kilo-octets.

0
Chuguniy