comment sortingez-vous la sortie par taille?

Comment sortinger du -sh /dir/* par taille? Je lis un site qui dit utilisation | sort -n | sort -n mais ce n'est évidemment pas vrai. Voici un exemple qui est faux.

 [~]# 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 dissortingbutions Linux), vous pouvez utiliser du -sh * | sort -h du -sh * | sort -h . L'option -h indique que l'input est le format lisible par l'homme (numéro avec l'unité).

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

Remarque:

Si vous utilisez Mac OSX, vous devez installer coreutils avec brew install coreutils , puis utiliser gsort comme rlocation de sort

Essayez d'utiliser l'indicateur -k pour countr les blocs de 1K au lieu d'utiliser des caractères lisibles par l'homme. Ensuite, vous avez une unité commune et pouvez facilement faire un sorting numérique.

 du -ck | sort -n 

Vous n'expliquez pas explicitement des 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 second appel au 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 ne disposez pas d'une version récente de GNU coreutils , vous pouvez appeler du sans -h pour get une sortie sortingable et produire une sortie conviviale avec un peu de post-traitement. Cela a l'avantage de fonctionner même si votre version du du n'a pas le drapeau -h .

 du -k | sort -n | awk ' function human(x) { s="kMGTEPYZ"; 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), changez 1024 à 1000 dans le corps de la boucle while. (Notez que ce 1000 dans la condition est destiné, de sorte que vous obtenez par exemple 1M plutôt que 1000k .)

Si votre du dispose d'une option pour afficher les tailles en octets (par exemple -b ou -B 1 – notez que cela peut avoir pour effet secondaire de countr les tailles de file réelles plutôt que l'utilisation du disque), ajoutez un espace au début de 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 un exercice.

Si vous n'avez pas de sort -h vous 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/' 

Cela obtient la list du du, sépare le suffixe, et sortinge en utilisant cela. Comme il n'y a pas de suffixe pour <1K, le premier sed ajoute un B (pour octet). Le second sed ajoute un délimiteur 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 files téraoctets, vous devrez convertir G en Y et T en Z. Finalement, nous sortingerons par les deux colonnes, puis nous replaceons le suffixe G.

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

 brew install coreutils 

Avec cela, vous aurez gsort , qui inclut le paramètre de command line -h .

Ce petit script Perl fait l'affaire. Sauvegardez-le en tant que duh (ou ce que vous voulez) et appelez-le avec duh /dir/*

 #!/usr/bin/perl -w use ssortingct; my @line; sub to_human_readable { my ($number) = @_; my @postfix = qw( k MGTP ); 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 sortingmlengthright { my ($txt, $len) = @_; if ( length($txt) >= $len ) { $txt = substr($txt,0,$len - 1) . " "; } else { $txt = $txt . " " x ($len - length($txt)); } return $txt; } sub sortingmlengthleft { 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 &sortingmlengthleft(&to_human_readable($line[0]),5)," "; # size print &sortingmlengthright($line[1],70),"\n"; # directory } close DF; 

Puisque Mac OS X n'a ​​pas l'option -h pour le sort , j'ai essayé et appris sed et awk pour une première tentative:

 du -sk * | sort -g | awk '{ numBytes = $1 * 1024; numUnits = split("BKMGTP", 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 ligne. Élargi, c'est:

 du -sk * | sort -g | awk '{ numBytes = $1 * 1024; numUnits = split("BKMGTP", 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; }' 

J'ai essayé sur Mac OS X Mavericks, Yosemite, Ubuntu 2014-04 avec awk étant le awk par défaut (qui est nawk , parce que awk et nawk pointent vers /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 un sharepoint assembly du système de files, 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 de http://www.geekology.co.za/ et earthinfo.org , ainsi que les canards infâmes de "Linux Server Hacks" de O'Reilly. Je l'adapte toujours à mes besoins. C'est encore un travail en cours (comme dans, je travaillais sur ce train ce matin.):

 #! /usr/bin/env bash ducks () { du -cks -x | sort -n | while read size fname; do for unit in k MGTPEZY; 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:~ $ 

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

Celui-ci gère les noms de files avec des espaces ou des apostrophes, et fonctionne sur les systèmes qui ne supportent pas 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 va sortinger la sortie par ordre décroissant de taille:

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

Cela va sortinger la sortie dans l'ordre croissant de la taille:

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

PS: ceci peut être utilisé pour sortinger par n'importe quelle colonne mais que les valeurs de colonne doivent être dans le 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 directorys récursivement, au bas sera le plus grand directory en Gigaoctets et en haut le plus petit en kilo-octets.

Pour sortinger par taille en Mo

 du --block-size=MiB --max-depth=1 path | sort -n 

Ce script est encore plus facile:

 for i in GMK; do du -h -d1 / | grep [0-9]$i | sort -n; done 

pour OSX

 du -h -k {PATH} | sort -n