Jak třídíte du -sh /dir/*
podle velikosti? Přečetl jsem jeden web, který řekl použití | sort -n
ale to zjevně není v pořádku. Zde je příklad, který je špatný.
[~]# 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
Pokud máte GNU coreutils (běžné ve většině distribucí Linuxu), můžete použít
du -sh -- * | sort -h
The -h
volba říká sort
, že vstupem je formát čitelný pro člověka (číslo s jednotkou; 1024, takže 1023 je považováno za méně než 1K, což se stane, aby odpovídalo tomu, co GNU) du -h
ano).
Tato funkce byla přidána do GNU Core Utilities 7.5 v srpnu 2009 .
Poznámka:
Pokud používáte starší verzi Mac OSX, musíte nainstalovat coreutils pomocí
brew install coreutils
, Pak použijtegsort
jako náhradu zasort
.Novější verze maker (ověřeno na Mojave) podporují
sort -h
nativně.
Zkuste použít příznak -k k počítání bloků 1 kB, které by bylo možné číst pomocí člověka. Pak máte společnou jednotku a můžete snadno provést číselné řazení.
du -ck | sort -n
Nevyžadujete výslovně lidské jednotky, ale pokud ano, existuje spousta způsobů, jak to udělat. Zdá se, že mnozí používají techniku bloků 1K výše a poté dorovnají druhý.
https://serverfault.com/questions/62411/how-can-i-sort-du-h-output-by-size
Pokud chcete vidět přidané jednotky KB, použijte:
du -k | sed -e 's_^\([0-9]*\)_\1 KB_' | sort -n
Pokud nemáte nedávná verze GNU coreutils , můžete zavolat du
bez -h
, Abyste získali výstup na pozadí, a produkují lidsky přívětivý výstup s malým následným zpracováním. To má tu výhodu, že pracuje, i když vaše verze du
nemá příznak -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}'
Pokud chcete přípony SI (tj. Násobky 1000 namísto 1024), změňte 1024 na 1000 v těle smyčky while
. (Všimněte si, že 1 000 ve stavu je určeno, takže získáte například 1M
, Nikoli 1000k
.)
Pokud má váš du
možnost zobrazit velikosti v bajtech (např. -b
Nebo -B 1
- mějte na paměti, že to může mít vedlejší účinek spočítání skutečných velikostí souborů spíše než využití disku) , přidejte mezeru na začátek s
(tj. s=" kMGTEPYZ";
), nebo přidejte if (x<1000) {return x} else {x/=1024}
na začátek funkce human
.
Zobrazení desetinné číslice pro čísla v rozsahu 1–10 je ponecháno jako cvičení pro čtenáře.
Pokud nemáte sort -h
můžeš to udělat:
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/'
Tím získáte seznam du, odděluje příponu a třídí ji pomocí. Protože neexistuje přípona pro <1K, první sed přidává B (pro byte). Druhé sed přidává oddělovač mezi číslici a příponu. Třetí sed převádí G na Z, takže je větší než M; Pokud máte soubory terabajtů, budete muset převést G na Y a T na Z. Nakonec rozdělíme podle dvou sloupců, pak nahradíme příponu G.
V OS X můžete nainstalovat potřebné coreutils pomocí Homebrew :
brew install coreutils
Díky tomu budete mít gsort
, který obsahuje -h
parametr příkazového řádku.
Tento malý Perl skript dělá trik. Uložte jej jako duh
(nebo co chcete) a zavolejte pomocí 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;
Protože Mac OS X nemá -h
možnost pro sort
, tak jsem se pokusil a naučil sed
a awk
pro první pokus:
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 to dlouhá řada. Rozšířeno, je to:
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;
}'
Vyzkoušel jsem to na Mac OS X Mavericks, Yosemite, Ubuntu 2014-04, kde awk
je výchozí awk
(což je nawk
, protože oba awk
a nawk
přejděte na /usr/bin/mawk
) nebo gawk a všichni pracovali.
Zde je ukázka výstupu na počítači 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
namísto du -sk *
, Viděl jsem v odpovědi Stefana, kde je také zobrazen celkový součet, a bez překročení bodu připojení souborového systému pomocí du -skcx *
Zde je to, co používám na Ubuntu 10.04, CentOS 5.5, FreeBSD a Mac OS X.
Myšlenku jsem si vypůjčil od www.geekology.co.za/ a earthinfo.org , stejně jako neslavného kachny z "Linux Server Hacks" "od O'Reilly. Stále to přizpůsobuji svým potřebám. Toto je stále nedokončená práce (Stejně jako v tom dnes ráno jsem pracoval na vlaku.):
#! /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
Zde je výstup:
[email protected]:~ $ ducks
32M src
42M .cpan
43M .macports
754M doc
865M Work
1G .Trash
4G Library
17G Downloads
30G Documents
56G total
[email protected]:~ $
Při absenci GNU sort -h
, mělo by to fungovat ve většině prostředí 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 }'
Zbavte se tohoto skriptu -
$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;}'
Příkaz:
du -ah . | sort -k1 -h | tail -n 50
Vysvětlení:
du -ah .
sort -k1 -h | tail -n 50
Největší je dole:
du -sh * | sort -h
Tento zpracovává názvy souborů mezerami nebo apostrofy a pracuje na systémech, které nepodporují xargs -d
nebo sort -h
:
du -s * | sort -n | cut -f2 | tr '\n' '\0' | xargs -0 -I {} du -sh "{}"
což má za následek:
368K diskmanagementd
392K racoon
468K coreaudiod
472K securityd
660K sshd
3.6M php-fpm
Tím se výstup utřídí v sestupném pořadí:
du -sh /var/* | sort -k 1rn
Tím se třídí výstup ve vzestupném pořadí velikosti:
du -sh /var/* | sort -k 1n
PS: to lze použít k seřazení podle libovolného sloupce, ale hodnoty tohoto sloupce by měly být ve stejném formátu
Testováno na Solarisu!
du -kh | sort -nk1 | grep [0-9]K && du -kh | sort -nk1 | grep [0-9]M && du -kh | sort -nk1 | grep [0-9]G
Tím budou rekurzivně generovány všechny velikosti adresářů, dole bude největší adresář v Gigabajtech a nahoře nejmenší v Kilobytech.