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
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 utilisezgsort
comme remplacement direct desort
.Les nouvelles versions de macOS (vérifiées sur Mojave) prennent en charge
sort -h
nativement.
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
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.
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.
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;
É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 *
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:~ $
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 }'
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;}'
Commande:
du -ah . | sort -k1 -h | tail -n 50
Explication:
du -ah .
sort -k1 -h | tail -n 50
Le plus gros est en bas:
du -sh * | sort -h
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
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
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.