J'ai besoin d'obtenir une liste de sortie lisible par l'homme.
Cependant, du
n'a pas d'option "trier par taille" et le piping vers sort
ne fonctionne pas avec l'indicateur lisible par l'homme.
Par exemple, exécuter:
du | sort -n -r
Affiche une utilisation du disque triée par taille (décroissant):
du |sort -n -r
65108 .
61508 ./dir3
2056 ./dir4
1032 ./dir1
508 ./dir2
Cependant, l'exécuter avec l'indicateur lisible par l'homme, ne se trie 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?
Depuis GNU coreutils 7.5 sorti en août 2009, sort
autorise un paramètre -h
, Qui autorise les suffixes numériques du type produit par du -h
:
du -hs * | sort -h
Si vous utilisez un tri qui ne prend pas en charge -h
, Vous pouvez installer GNU Coreutils. Par exemple sur un Mac OS X plus ancien:
brew install coreutils
du -hs * | gsort -h
De sort
manuel :
-h, --human-numeric-sort compare human readable numbers (e.g., 2K 1G)
du | sort -nr | cut -f2- | xargs du -hs
@Douglas Leeder, encore une réponse: Triez la sortie lisible par l'homme de du -h en utilisant un autre outil. Comme Perl!
du -h | Perl -e 'sub h{%h=(K=>10,M=>20,G=>30);($n,$u)=shift=~/([0-9.]+)(\D)/;
return $n*2**$h{$u}}print sort{h($b)<=>h($a)}<>;'
Fractionner sur deux lignes pour s'adapter à l'affichage. Vous pouvez l'utiliser de cette façon ou en faire une doublure, cela fonctionnera dans les deux sens.
Production:
4.5M .
3.7M ./colors
372K ./plugin
128K ./autoload
100K ./doc
100K ./syntax
EDIT: Après quelques parties de golf à PerlMonks , le résultat final est le suivant:
Perl -e'%h=map{/.\s/;99**(ord$&&7)-$`,$_}`du -h`;die@h{sort%h}'
Il y a un outil extrêmement utile que j'utilise appelé ncd qui est conçu pour trouver ces dossiers et fichiers saturés à haute utilisation de disque et les supprimer. Il est basé sur une console, rapide et léger, et propose des packages sur toutes les principales distributions.
du -k * | sort -nr | cut -f2 | xargs -d '\n' du -sh
Autant que je sache, vous avez trois options:
du
pour trier avant l'affichage.sort
pour prendre en charge les tailles humaines pour le tri numérique.Vous pouvez également faire du -k
et vivre avec des tailles en KiB.
Pour l'option 3, vous pouvez 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
J'ai également eu ce problème et j'utilise actuellement une solution de contournement:
du -scBM | sort -n
Cela ne produira pas de valeurs mises à l'échelle, mais produira toujours la taille en mégaoctets. C'est moins que parfait, mais pour moi c'est mieux que rien (ou afficher la taille en octets).
Trouvé cette publication ailleurs. Par conséquent, ce script Shell fera ce que vous voulez sans appeler deux fois du
sur tout. 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
}}}'
Exécuter ceci dans mon .vim
le répertoire donne:
4.4M .
3.6M ./colors
372.0K ./plugin
128.0K ./autoload
100.0K ./syntax
100.0K ./doc
(J'espère que 3,6 millions de jeux de couleurs ne sont pas excessifs.)
Cette version utilise awk
pour créer des colonnes supplémentaires pour les clés de tri. Il n'appelle du
qu'une seule fois. La sortie doit ressembler exactement à du
.
Je l'ai divisé en plusieurs lignes, mais il peut être recombiné en un seul revêtement.
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:
Essayez-le sans la commande cut
pour voir ce qu'il fait.
Voici une version qui fait le tri dans le script AWK et 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]]}'
Voici un exemple qui montre les répertoires sous une forme résumée plus compacte. Il gère les espaces dans le répertoire/noms de fichiers.
% 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
trier les fichiers par taille en Mo
du --block-size=MiB --max-depth=1 path | sort -n
J'ai un simple python pour du appelé dutop . Notez que nous (les responsables de coreutils) envisage d'ajouter la fonctionnalité de tri pour trier "humain" sortie directement.
J'en ai un autre:
$ du -B1 | sort -nr | Perl -MNumber::Bytes::Human=format_bytes -F'\t' -lane 'print format_bytes($F[0])."\t".$F[1]'
Je commence à aimer Perl. Vous devrez peut-être faire un
$ cpan Number::Bytes::Human
première. À tous les hackers de Perl: Oui, je sais que la partie de tri peut également être effectuée en Perl. Probablement le du part aussi.
Cet extrait a été éhonté de "Jean-Pierre" de http://www.unix.com/Shell-programming-scripting/32555-du-h-sort.html . Existe-t-il un moyen de mieux le créditer?
du -k | sort -nr | awk '
BEGIN {
split("KB,MB,GB,TB", Units, ",");
}
{
u = 1;
while ($1 >= 1024) {
$1 = $1 / 1024;
u += 1
}
$1 = sprintf("%.1f %s", $1, Units[u]);
print $0;
}
'
Utilisez le drapeau "-g"
-g, --general-numeric-sort
compare according to general numerical value
Et sur mon répertoire/usr/local produit une sortie comme celle-ci:
$ du |sort -g
0 ./lib/site_Ruby/1.8/rubygems/digest
20 ./lib/site_Ruby/1.8/rubygems/ext
20 ./share/xml
24 ./lib/Perl
24 ./share/sgml
44 ./lib/site_Ruby/1.8/rubygems/package
44 ./share/mime
52 ./share/icons/hicolor
56 ./share/icons
112 ./share/Perl/5.10.0/YAML
132 ./lib/site_Ruby/1.8/rubygems/commands
132 ./share/man/man3
136 ./share/man
156 ./share/Perl/5.10.0
160 ./share/Perl
488 ./share
560 ./lib/site_Ruby/1.8/rubygems
604 ./lib/site_Ruby/1.8
608 ./lib/site_Ruby
Trouvé celui-ci en ligne ... semble fonctionner OK
du -sh * | tee /tmp/duout.txt | grep G | sort -rn ; cat /tmp/duout.txt | grep M | sort -rn ; cat /tmp/duout.txt | grep K | sort -rn ; rm /tmp/duout.txt
Voici la méthode simple que j'utilise, l'utilisation des ressources très faible et vous obtient ce dont vous avez besoin:
du --max-depth=1 | sort -n | awk 'BEGIN {OFMT = "%.0f"} {print $1/1024,"MB", $2}'
0 MB ./etc
1 MB ./mail
2 MB ./tmp
123 MB ./public_html
J'ai appris awk en concoctant cet exemple hier. Cela a pris du temps, mais c'était très amusant et j'ai appris à utiliser awk.
Il ne s'exécute qu'une seule fois et a une sortie très similaire à du -h
du --max-depth=0 -k * | sort -nr | awk '{ if($1>=1024*1024) {size=$1/1024/1024; unit="G"} else if($1>=1024) {size=$1/1024; unit="M"} else {size=$1; unit="K"}; if(size<10) format="%.1f%s"; else format="%.0f%s"; res=sprintf(format,size,unit); printf "%-8s %s\n",res,$2 }'
Il affiche des nombres inférieurs à 10 avec un point décimal.
Un autre:
du -h | Perl -e'
@l{ K, M, G } = ( 1 .. 3 );
print sort {
($aa) = $a =~ /(\w)\s+/;
($bb) = $b =~ /(\w)\s+/;
$l{$aa} <=> $l{$bb} || $a <=> $b
} <>'
du -cka --max-depth = 1/var/log | sort -rn | tête -10 | awk '{print ($ 1)/1024, "MB", $ 2'}
Si vous devez gérer des espaces, vous pouvez utiliser les éléments suivants
du -d 1| sort -nr | cut -f2 | sed 's/ /\\ /g' | xargs du -sh
L'instruction sed supplémentaire aidera à atténuer les problèmes avec les dossiers avec des noms tels que le support d'application
Voilà:
du -sk /var/log/* | sort -rn | awk '{print $2}' | xargs -ia du -hs "a"
Il y a beaucoup de réponses ici, dont beaucoup sont des doublons. Je vois trois tendances: passer par un deuxième appel du, utiliser du code Shell/awk compliqué et utiliser d'autres langages.
Voici une solution compatible POSIX utilisant d et awk qui devrait fonctionner sur chaque système.
J'ai adopté une approche légèrement différente, en ajoutant -x
Pour nous assurer de rester sur le même système de fichiers (je n'ai besoin de cette opération que lorsque je manque d'espace disque, alors pourquoi éliminer les éléments que j'ai montés dans ceci FS arbre ou déplacé et lié en retour?) et affichant des unités constantes pour faciliter l'analyse visuelle. Dans ce cas, je choisis généralement pas pour trier ainsi Je peux mieux voir la structure hiérarchique.
Sudo du -x | awk '
$1 > 2^20 { s=$1; $1=""; printf "%7sG%s\n", sprintf("%.2f",s/2^21), $0 }'
(Comme il s'agit d'unités cohérentes, vous pouvez ensuite ajouter | sort -n
Si vous voulez vraiment des résultats sort ed.)
Cela filtre tout répertoire dont le contenu (cumulatif) ne dépasse pas 512 Mo, puis affiche les tailles en gigaoctets. Par défaut, du utilise une taille de bloc de 512 octets (donc la condition awk de 220 blocs est de 512 Mo et ses 221 diviseur convertit les unités en Go - nous pourrions utiliser du -kx
avec $1 > 512*1024
et s/1024^2
pour être plus lisible par l'homme). À l'intérieur de la condition awk, nous définissons s
à la taille afin de pouvoir le supprimer de la ligne ($0
). Cela conserve le délimiteur (qui est réduit à un seul espace), donc le %s
Final représente un espace, puis le nom du répertoire agrégé. %7s
Aligne la taille arrondie de %.2f
Go (augmentez à %8s
Si vous avez> 10 To).
Contrairement à la plupart des solutions ici, cela prend correctement en charge les répertoires avec des espaces dans leurs noms (bien que every solution, y compris ceci un, va mal gérer les noms de répertoires contenant des sauts de ligne).
Une autre awk
solution -
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~/Desktop/Reference]$ 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;}'
15.92MB ./Personal
13.82MB ./Personal/Docs
2.35MB ./Work Docs
1.59MB ./Work Docs/Work
1.46MB ./Personal/Raa
584.00KB ./scan 1.pdf
544.00KB ./Personal/Resume
44.00KB ./Membership.xlsx
16.00KB ./Membership Transmittal Template.xlsx
commande: ncdu
Navigation dans l'annuaire, tri (nom et taille), graphique, lisible par l'homme, etc ...
J'utilisais la solution fournie par @ptman, mais un récent changement de serveur l'a rendue non viable. Au lieu de cela, j'utilise le script bash suivant:
#!/bin/bash
# File: duf.sh
# list contents of the current directory by increasing
#+size in human readable format
# for some, "-d 1" will be "--maxdepth=1"
du -k -d 1 | sort -g | awk '
{
if($1<1024)
printf("%.0f KB\t%s",$1,$2);
else if($1<1024*1024)
printf("%.1f MB\t%s",$1/1024,$2);
else
printf("%.1f GB\t%s",$1/1024/1024,$2);
}'
du -s * | sort -nr | coupe -f2 | xargs du -sh
Voici un exemple
du -h /folder/subfolder --max-depth=1 | sort -hr
Retour:
233M /folder/subfolder
190M /folder/subfolder/myfolder1
15M /folder/subfolder/myfolder4
6.4M /folder/subfolder/myfolder5
4.2M /folder/subfolder/myfolder3
3.8M /folder/subfolder/myfolder2
Vous pouvez également ajouter | head -10
pour rechercher les 10 premiers ou un nombre quelconque de sous-dossiers dans le répertoire spécifié.
Ceci est l'alias que j'ai dans mon profil.
alias du = 'Sudo du -xh --max-depth = 1 | trier -h '
sort -h est ce qui aide vraiment ici à la question posée.
Une autre option utile est du -x pour rester sur le même système de fichiers; Sudo aide également à ne pas voir les erreurs s'il existe des répertoires qui ne sont pas lisibles par tous. Aussi, je fais toujours du --max-depth = 1, puis je descends plus loin, etc.
du
!Comme il y a déjà beaucoup de réponses, je poste juste mon propre script là-bas. J'utilise depuis plus de huit ans maintenant.
Cela pourrait être géré par
/somepath/rdu.sh [-b] [/somepath] [minSize]
où
-b
dire d'utiliser nombre d'octets au lieu de block compter256Mb
.La sortie pourrait ressembler à:
\___ 3.01G 21.67% .cache
| \___ 1.37G 45.54% mozilla
| | \___ 1.37G 100.00% firefox
| | | \___ 581.71M 41.48% billiethek.default
| | | | \___ 522.64M 89.85% cache2
| | | | | \___ 522.45M 99.96% entries
...
Il y a le script:
#!/bin/bash
if [ "$1" == "-b" ] ;then
shift
units=(b K M G T P)
duargs="-xbs"
minsize=${2:-$((256*1024**2))}
else
units=(K M G T P)
duargs="-xks"
minsize=${2:-$((256*1024))}
fi
humansize() {
local _c=$1 _i=0
while [ ${#_c} -gt 3 ] ;do
((_i++))
_c=$((_c>>10))
done
_c=$(( ( $1*1000 ) >> ( 10*_i ) ))
printf ${2+-v} $2 "%.2f%s" ${_c:0:${#_c}-3}.${_c:${#_c}-3} ${units[_i]}
}
percent() {
local p=000$((${1}00000/$2))
printf ${3+-v} $3 "%.2f%%" ${p:0:${#p}-3}.${p:${#p}-3}
}
device=$(stat -c %d "${1:-.}")
printf -v sep "%16s" ""
rdu() {
local _dir="$1" _spc="$2" _crt _siz _str _tot _pct
while read _siz _crt;do
if [ "$_crt" = "total" ]; then
_tot=$_siz
else
[ "$_tot" ] || _tot=$_siz
if [ $_siz -gt $minsize ];then
humansize $_siz _str
percent $_siz $_tot _pct
printf "%s\___ %7s%s%7s%s%s\n" \
"$_spc" $_str "$sep" $_pct "$sep" "${_crt##*/}"
[ -d "$_crt" ] &&
[ $(stat -c %d "$_crt") -eq $device ] &&
rdu "$_crt" "| $_spc"
fi
fi
done < <(
find "$_dir" -mindepth 1 -maxdepth 1 -xdev \
\( -type f -o -type d \) -printf "%D;%p\n" |
sed -ne "s/^${device};//p" |
tr \\n \\0 |
xargs -0 du ${duargs}c |
sort -nr
)
}
rdu "${1:-.}"
Et non, je ne les posterai pas sur Git***.xxx
.
Vous pouvez les montrer là-bas ou télécharger le script là-bas.
Voici ma solution, un simple script bash qui n'appelle du une fois et ne vous montre que les répertoires de taille 1 Mo ou plus:
#!/bin/env bash
# Usage: my_du.sh [subdirectory levels]
# For efficiency, only calls "du" once, and stores results in a temp file
# Stephen Becker, 2/23/2010
if [ $# -gt 0 ]; then
# You may prefer, as I do, to just summarize the contents of a directory
# and not view the size of its subdirectories, so use this:
du -h --max-depth $1 > temp_du_file
else
du -h > temp_du_file
fi
# Show all directories of size > 1 GB:
cat temp_du_file | grep "^\([0-9]\|\.\)\+G" | sort -nr
# Show all directories of size > 1 MB:
cat temp_du_file | grep "^\([0-9]\|\.\)\+M" | sort -nr
rm temp_du_file
Au moins avec les outils habituels, cela sera difficile en raison du format des nombres lisibles par l'homme (notez que le tri fait un "bon travail" ici car il trie les nombres - 508, 64, 61, 2, 2 - il ne peut tout simplement pas trier les nombres à virgule flottante avec un multiplicateur supplémentaire).
J'essaierais l'inverse - utiliser la sortie de "du | sort -n -r" et ensuite convertir les nombres au format lisible par l'homme avec un script ou un programme.
Ce que vous pouvez essayer, c'est:
for i in `du -s * | sort -n | cut -f2`
do
du -h $i;
done
J'espère que cela pourra aider.
du | sort -nr | awk '{ cmd = "du -h -d0 "$2"| cut -f1"; cmd | getline human; close(cmd); print human"\t"$2 }'
La solution suivante est similaire à l'original de cadrian mais cela n'exécutera que 2 commandes du par opposition à un du pour chaque répertoire de l'arborescence.
du -hs `du |sort -g |cut -f2- `
Cependant, la solution de Cardrian est plus robuste car ce qui précède ne fonctionnera pas pour les arbres très peuplés car elle pourrait dépasser la limite de la taille des arguments transmis à du
Librement basé sur la logique de ce one-liner , j'ai écrit un script qui fournit une sortie triée lisible par l'homme (1). Autre que d'exiger le -h
indicateur de lisibilité, il ne nécessite aucune autre commande non compatible POSIX.
Il est disponible sur https://github.com/pleappleappleap/sorted-human-d .
Pourquoi ne pas jeter un autre chapeau sur le ring ... c'est une vieille question, mais voici un exemple qui est (principalement) un script Shell pur (fwiw) - c'est-à-dire, juste bash et pas Perl/python/awk/etc. Donc, dans ce sens, cela offre peut-être quelque chose de nouveau à la discussion (ou pas). Il calcule la taille du fichier une seule fois, mais imprime dans différentes unités (ma préférence). (La version non simplifiée inclut des getopts qui excluent "GB" si non souhaité.)
#!/bin/bash
printf -- ' %9s %9s %9s %-30s\n' 'K' 'M' 'G' 'Path'
printf -- ' %9s %9s %9s %-30s\n' '--------' '--------' '--------' '-----------'
du -sk "$@" | while read val; do
file=$(echo "$val" | cut -f2-)
size_k=$(echo "$val" | cut -f1)
printf ' %9s %9s %9s %-30s\n' \
${size_k} \
$(( size_k / 1024 )) \
$(( size_k / 1024 / 1024 )) \
"$file"
done | sort -n
Trie par ordre décroissant.
du -s ./* | sort -n| cut -f 2-| xargs du -sh {}