我怎么能按大小sorting

我需要得到一个可读的du输出列表。

但是, du没有“按尺寸sorting”选项,并且sortpipe道不能与人类可读标志一起使用。

例如,运行:

 du | sort -n -r 

按大小(降序)输出sorting后的磁盘使用情况:

 du |sort -n -r 65108 . 61508 ./dir3 2056 ./dir4 1032 ./dir1 508 ./dir2 

但是,使用人类可读的标志运行它,不能正确sorting:

 du -h | sort -n -r 508K ./dir2 64M . 61M ./dir3 2.1M ./dir4 1.1M ./dir1 

有没有人知道按尺寸sorting的方法?

从2009年8月发布的GNU coreutils 7.5开始, sort允许使用-h参数,该参数允许du -h生成的数字后缀:

 du -hs * | sort -h 

对于Mac,你可以使用这个(来自评论):

 brew install coreutils du -hs * | gsort -h 

sort手册:

-h, --human-numeric-sort compare human readable numbers (eg, 2K 1G)

 du | sort -nr | cut -f2- | xargs du -hs 

@Douglas Leeder,还有一个答案:使用另一个工具对du -h的可读输出进行sorting。 像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)}<>;' 

分成两行以适应显示。 你可以这样使用它,或者使它成为一个单行,它将以任何方式工作。

输出:

 4.5M . 3.7M ./colors 372K ./plugin 128K ./autoload 100K ./doc 100K ./syntax 

编辑: PerlMonks几轮高尔夫后,最终的结果如下:

 perl -e'%h=map{/.\s/;99**(ord$&&7)-$`,$_}`du -h`;die@h{sort%h}' 

有一个非常有用的工具,我使用称为ncdu是专为find那些讨厌的高磁盘使用率的文件夹和文件,并删除它们。 它基于控制台,快速而轻便,并且在所有主要的发行版上都有软件包。

 du -k * | sort -nr | cut -f2 | xargs -d '\n' du -sh 

据我所见,你有三个select:

  1. 在显示之前更改。
  2. 改变sort以支持人物尺寸进行数字sorting。
  3. 后处理从sorting的输出更改基本输出到人类可读。

你也可以做du -k并在KiB生活的大小。

对于选项3,您可以使用以下脚本:

 #!/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 

我也有这个问题,我目前正在使用一种解决方法:

 du -scBM | sort -n 

这不会产生缩放值,但总是以兆字节产生大小。 这是不完美的,但对我来说,总比没有好(或以字节显示大小)。

在其他地方find这个帖 因此,这个shell脚本可以做任何你想做的事,而不用在任何事情上调用du两次。 它使用awk将原始字节转换为可读格式。 当然,格式有些不同(一切都打印到小数点后一位精度)。

 #/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 }}}' 

在我的.vim目录中运行这个产生:

 4.4M . 3.6M ./colors 372.0K ./plugin 128.0K ./autoload 100.0K ./syntax 100.0K ./doc 

(我希望3.6M的配色scheme不是太多。)

以下是一个以更简洁的摘要forms显示目录的示例。 它处理目录/文件名中的空格。

 % 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 

这个版本使用awk为分类键创build额外的列。 它只叫一次。 输出应该看起来像du

我把它分成了多行,但可以重新组合成一行。

 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 

说明:

  • BEGIN – 创build一个string来索引,用K,M,G代替1,2,3,如果没有单位(大小小于1K),则不匹配,返回0(完美! )
  • 打印新的字段 – 单位,值(使alpha-sort正常工作,它是零填充,固定长度)和原始行
  • 索引大小字段的最后一个字符
  • 拉出大小的数字部分
  • 对结果进行sorting,放弃额外的列

尝试没有cut命令,看看它在做什么。

这是一个在AWK脚本中进行sorting的版本,不需要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]]}' 

我有一个简单但有用的python封装du的叫dutop 。 请注意,我们(coreutils维护者)正在考虑添加function来直接sorting“人类”输出。

又有一个:

 $ du -B1 | sort -nr | perl -MNumber::Bytes::Human=format_bytes -F'\t' -lane 'print format_bytes($F[0])."\t".$F[1]' 

我开始喜欢perl。 你可能需要做一个

 $ cpan Number::Bytes::Human 

第一。 对所有perl黑客来说:是的,我知道sorting部分也可以在perl中完成。 也许是du部分。

按MB大小sorting文件

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

使用“-g”标志

  -g, --general-numeric-sort compare according to general numerical value 

并在我的/ usr /本地目录产生这样的输出:

 $ 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 

这个片段是从http://www.unix.com/shell-programming-scripting/32555-du-h-sort.html&#x7684; “Jean-Pierre”中无耻地截获的。 有什么办法可以让他更好的信任他?

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

另一个:

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

find这一个在线…似乎工作确定

 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 

我昨天从这个例子中学习了awk。 花了一些时间,但是非常有趣,我学会了如何使用awk。

它只运行一次,它的输出与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 }' 

它显示10位以下的小数点后一位数字。

这里是我使用的简单的方法,非常低的资源使用率,并得到你所需要的:

 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 

du -cka –max-depth = 1 / var / log | sort -rn | 头-10 | awk'{print($ 1)/ 1024,“MB”,$ 2'}

如果您需要处理空间,您可以使用以下内容

  du -d 1| sort -nr | cut -f2 | sed 's/ /\\ /g' | xargs du -sh 

额外的sed语句将有助于缓解具有名称的文件夹(如“应用程序支持”)的问题

瞧:

 du -sk /var/log/* | sort -rn | awk '{print $2}' | xargs -ia du -hs "a" 

另一个awk解决scheme –

 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 

我一直在使用@ptman提供的解决scheme,但最近的服务器更改使其不再可行。 相反,我正在使用下面的bash脚本:

 #!/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); }' 

这里有很多答案,其中许多是重复的。 我看到了三个趋势:使用复杂的shell / awk代码,并使用其他语言,进行第二次调用。

这是一个符合POSIX标准的解决scheme,使用du和awk ,可以在每个系统上运行。

我采取了一个稍微不同的方法,join-x以确保我们保持在同一个文件系统上(当我在磁盘空间不足时,我只需要这个操作,所以为什么要删除我在这个FS树中挂载的东西或移动和符号链接回来?)和显示不变的单位,使更容易的视觉parsing。 在这种情况下,我通常select进行sorting,以便更好地查看分层结构。

 sudo du -x | awk ' $1 > 2^20 { s=$1; $1=""; printf "%7sG%s\n", sprintf("%.2f",s/2^21), $0 }' 

(因为这是一致的单位,所以你可以追加| sort -n如果你真的想sorting结果。)

这将过滤掉(累积的)内容不能超过512MB的任何目录,然后以千兆字节显示大小。 默认情况下,du使用512字节的块大小(所以awk的2个20块的条件是512MB,它的2 21除数将单位转换为GB – 我们可以用$1 > 512*1024s/1024^2来使用du -kx更加人性化)。 在awk条件下,我们设置s的大小,所以我们可以从行( $0 )中删除它。 这将保留分隔符(它被折叠为一个空格),所以最后的%s代表一个空格,然后是聚合目录的名称。 %7salignment圆形的%.2f GB大小(如果大于10TB,则增加到%8s )。

与这里的大多数解决scheme不同, 这可以正确地支持名称中包含空格的目录 (尽pipe每个解决scheme(包括这个解决scheme)都会错误地处理包含换行符的目录名称)。

至less在通常的工具中,由于人类可读的数字的格式,这将是困难的(请注意,sorting在这里sorting的数字是“好工作” – 508,64,61,2,2 – 它只是不能用另外的乘数对浮点数进行sorting)。

我会尝试反过来 – 使用“du | sort -n -r”的输出,然后用一些脚本或程序将这些数字转换为可读的格式。

你可以尝试的是:

 for i in `du -s * | sort -n | cut -f2` do du -h $i; done 

希望有所帮助。

 du | sort -nr | awk '{ cmd = "du -h -d0 "$2"| cut -f1"; cmd | getline human; close(cmd); print human"\t"$2 }' 

下面的解决scheme类似于cadrian的原始版本,但是它只能运行2个du命令,而不是每个目录的du。

 du -hs `du |sort -g |cut -f2- ` 

不过,Cardrian的解决scheme更为稳健,因为上述方法对于人口稠密的树木来说不起作用,因为它可能会超过传递给du的参数大小的限制

这是我的解决scheme,一个简单的bash脚本,只能调用一次,并且只显示大小为1 MB或更大的目录:

 #!/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