我需要获取人类可读的du输出列表。

但是,du没有“按大小排序”选项,并且配给sort的管道不适合人类可读的标志。

例如,运行:

du | sort -n -r 


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

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


但是,使用人类可读的标志,排序不正确:

du -h | sort -n -r

508K    ./dir2
64M     .
61M     ./dir3
2.1M    ./dir4
1.1M    ./dir1


有人知道一种按大小对du -h进行排序的方法吗?

评论

这是一个非常相关的问题:serverfault.com/q/737537/35034

你看过这个吗? unix.stackexchange.com/questions/4681/…它几乎是重复的,值得金。您执行常规du,但将-h添加到sort命令。您可以添加-rh,以便最大的在文件中排在首位,否则需要使用tail来查看空格键。

#1 楼

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

du -hs * | sort -h


不支持-h的用户,可以安装GNU Coreutils。例如。在较旧的Mac OS X上:

brew install coreutils
du -hs * | gsort -h


来自sort手册:

-h, --human-numeric-sort compare human readable numbers (e.g., 2K 1G)

评论


手册的相关部分:gnu.org/software/coreutils/manual/…

–寡妇
2011-2-9在11:13

易于使用自制软件在OS X上安装-brew install coreutils。

–理查德·普里耶(Richard Poirier)
2011年5月1日18:53

好一个!我个人总是做du -BM | sort -nr作为一种解决方法-如果有人被旧的coreutils所困扰,它已经足够让人可读,并且可以进行排序。

–chutz
2012年5月24日9:06

如果通过Homebrew在OSX上使用,请注意,您现在需要使用gsort而不是sort:du -hs * | gsort -h

–布莱恩·克莱恩(Brian Cline)
2013年12月16日上午8:45

@ PaulDraper,du -BM以MB为单位打印所有内容,因此168K的文件实际显示为0M。除非有其他版本差异,否则我不知道。我的du版本仅显示整数兆字节值。

–chutz
2014年2月1日在15:12

#2 楼

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


评论


而且它将进行大量重复计数。

–道格拉斯·里德(Douglas Leeder)
09年2月25日在13:55

首先,它会执行正常的du-然后,对于每个条目,它都会重新计算尺寸,只是以人类可读的形式打印出来。

–道格拉斯·里德(Douglas Leeder)
09年2月25日在14:22

@Douglas Leeder:您应该进行重复计数,但是认为第二个du并不是从冷缓存开始的(感谢OS)@hasen j:xargs是一个非常有用的命令,它将其stdin拆分并将其作为参数提供给定命令

– cadrian
2009年2月25日14:52

Chris的优势实际上是优越的,因为它可以处理包含空格的路径。兄弟们,以自己的方式投票。

–rbright
09年2月25日在22:45

丑陋,但跨平台:)。

–voretaq7
2011年11月29日23:06

#3 楼

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


评论


由于模具的原因,您的简短版本在stderr上输出,您可以更改它以使其在stdout上输出吗?

–丹尼斯·威廉姆森
09年9月4日在16:16

将模具更改为打印件,它将进入标准输出。这只是两个字符。

–亚当·贝莱尔(Adam Bellaire)
09年9月9日于17:55

在ubuntu上工作!

– marinara
2012年4月26日在8:22

令人印象深刻的Perl黑客技术

– NandoP
2013年11月13日在5:00

结果是相反的顺序:(

– RSFalcon7
2014年4月1日在22:28

#4 楼

我使用了一个名为ncdu的非常有用的工具,该工具旨在查找那些讨厌的高磁盘使用率文件夹和文件,并将其删除。它基于控制台,快速,轻便,并且在所有主要发行版中均提供了软件包。

评论


很好...如果结果可以按标准输出,我会更好...我很懒,无法阅读手册

– ojblass
09年6月27日在5:17

gt5是同一脉络;它的杀手级功能正在显示增长。

–东武
2010年7月1日在16:16

太棒了!如果您只想识别大型目录,则比使用du快得多。

– BurninLeo
15年9月16日在17:49

#5 楼

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


评论


不能与du -k --total一起使用,在末尾给出错误du:无法访问“ total”:没有这样的文件或目录

–滞后反射
2015年1月3日在2:51



我更喜欢这个其他答案。您将如何只显示前50个结果?

–茂
16年1月12日在4:25

@Mauro-通过添加`|将结果传递到头部头-50`。

– SamuelLelièvre
18年2月21日在10:32

#6 楼

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

du -scBM | sort -n


这不会产生缩放值,但始终会产生兆字节大小。那还不算完美,但是对我来说总比没有好(或者以字节为单位显示大小)。

评论


我喜欢-BM开关,它与-m基本相同,但是它具有显示大小和后缀M的优点,因此您得到10M,这比10清楚得多:)

–汤姆·费纳(Tom Feiner)
09年2月25日在14:02

这是我到目前为止在此页面上看到的最简单的解决方案,谢谢!

–杰夫·奥尔森(Jeff Olson)
2015年11月5日在16:35

#7 楼

据我所知,您有三个选择:



更改du以便在显示之前进行排序。
更改sort可以支持人员大小以进行数字排序。
后处理从排序的输出将基本输出更改为人类可读。

还可以执行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


#8 楼

在其他地方找到此帖子。因此,此Shell脚本将完成您想要的操作,而无需对所有内容调用两次du。它使用awk将原始字节转换为人类可读的格式。当然,格式略有不同(所有内容都打印为小数点后一位精度)。

#/bin/bash
du -B1 | sort -nr  |awk '{sum=;
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 ;break
}}}'


在我的.vim目录中运行此命令将产生:

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


(我希望360万种配色不要过多。)

评论


我也有Perl的答案,但我认为这可能会让人们讨厌我:du -B1 |排序-nr | perl -e'%h =(0 => b,1 => K,2 => M,3 => G);对于(<>){($ s,@ f)= split / \ s + /; $ e = 3; $ e-- while(1024 ** $ e> $ s); $ v =($ s /(1024 ** $ e)); printf“%-8s%s \ n”,sprintf($ v> = 100?“%d%s”:“%.1f%s”,$ s /(1024 ** $ e),$ h {$ e}),@ f;}'

–亚当·贝莱尔(Adam Bellaire)
09年2月25日在14:40

即使Perl答案实际上使它的格式更接近du。尽管四舍五入已关闭...看来du总是给出ceil()而不是round()

–亚当·贝莱尔(Adam Bellaire)
09年2月25日在14:41

嘿,我为什么在那里使用哈希?应该是一个数组...早脑抱怨...

–亚当·贝莱尔(Adam Bellaire)
09年2月25日在15:33

添加了更好的Perl解决方案作为另一个答案。

–亚当·贝莱尔(Adam Bellaire)
09年2月25日在21:06

文件名包含空格时,两个版本均会失败

– Vi。
2010年11月2日,17:54



#9 楼

此版本使用awk为排序键创建额外的列。它仅调用一次du。输出看起来应该与du完全一样。

我将其拆分为多行,但可以将其重组为一个线性。

du -h |
  awk '{printf "%s %08.2f\t%s\n", 
    index("KMG", substr(, length())),
    substr(, 0, length()-1), 
du -h |
   awk '{idx = sprintf("%s %08.2f %s", 
         index("KMG", substr(, length())),
         substr(, 0, length()-1), q4312078q);
         lines[idx] = q4312078q}
    END {c = asorti(lines, sorted);
         for (i = c; i >= 1; i--)
           print lines[sorted[i]]}'
}' | sort -r | cut -f2,3


说明:


BEGIN-创建一个要索引的字符串,以K,M, G用于按单位分组,如果没有单位(大小小于1K),则没有匹配项,并且返回零(完美!)
打印新字段-单位,值(以使alpha-排序工作正确,它是零填充的,定长的),并原始行
索引大小字段的最后一个字符
提取大小的数字部分
对结果进行排序,丢弃多余的内容列

不用cut命令就可以尝试看看它在做什么。

这是一个可以在AWK脚本中进行排序并且不需要cut的版本:

q4312078q

评论


谢谢!这是在OS X 10.6中对我有用的第一个示例,不计算perl / phython脚本。再次感谢您的良好解释。总是很高兴学习新东西。肯定是一个强大的工具。

–狼
2011年5月4日在12:09

对此非常感谢。我将du更改为du -sh *,以仅显示立即文件和目录,而没有递归下降。

–汉卡
2016年12月9日在22:01

#10 楼

这是一个以更紧凑的摘要形式显示目录的示例。它处理目录/文件名中的空格。

% 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


评论


警告macOS / OSX用户,xargs的Mac版本不支持-d标志,如果省略它,则任何包含空格的目录都将分别解析每个单词,这当然会失败。

–心脏病学
17年7月19日在4:40



#11 楼

按MB大小排序文件

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


#12 楼

我有一个du的简单但有用的python包装器,称为dutop。
请注意,我们(coreutils维护者)正在考虑添加该功能以对“人”的输出进行直接排序。

评论


+1是一种罕见的有效例外,可以“做一件事情并正确地做到这一点”。除非有人能够理解SI前缀和/或二进制前缀。

– Joachim Sauer
09年3月18日在22:20

正如ptman在下面提到的:ta da! (新的排序标志)

–东武
2010年7月1日于16:13

#13 楼

还有另一个:

$ 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黑客:是的,我知道排序部分也可以在perl中完成。可能也是du部分。

#14 楼

这个片段是从http://www.unix.com/shell-programming-scripting/32555-du-h-sort.html的“让·皮埃尔(Jean-Pierre)”无耻地sn取的。我有办法更好地相信他吗?

du -k | sort -nr | awk '
     BEGIN {
        split("KB,MB,GB,TB", Units, ",");
     }
     {
        u = 1;
        while ( >= 1024) {
            =  / 1024;
           u += 1
        }
         = sprintf("%.1f %s", , Units[u]);
        print q4312078q;
     }
    '


评论


我认为如果这是一个非常大的数字,则该设备不见了,显示的数字很小...尝试23423423432423

–nonopolarity
15年4月22日在9:18

#15 楼

使用“ -g”标志

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


,在我的/ usr / local目录中产生如下输出:

$ 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


评论


但是,这并没有提供人类可读的输出,而这正是OP所寻找的。

–詹妮·D。
09年2月25日在17:24

#16 楼

在网上找到了这一个...似乎可以正常工作

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


评论


基于这种单行代码,我松散地创建了一个脚本,用于提供人类可读的排序du(1)输出。请参考我的答案,serverfault.com / a / 937459/218692。

– Tripp动力学
18-10-26在22:10



#17 楼

另一个:

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


#18 楼

我从昨天炮制这个例子中学到了awk。它花了一些时间,但是却非常有趣,而且我学会了如何使用awk。

它只运行一次du,并且输出与du -h
du --max-depth=0 -k * | sort -nr | awk '{ if(>=1024*1024) {size=/1024/1024; unit="G"} else if(>=1024) {size=/1024; unit="M"} else {size=; unit="K"}; if(size<10) format="%.1f%s"; else format="%.0f%s"; res=sprintf(format,size,unit); printf "%-8s %s\n",res, }'


它显示小于10的数字,带有一个小数点。

#19 楼

这是我使用的简单方法,资源使用率非常低,可以满足您的需求:

du --max-depth=1 | sort -n | awk 'BEGIN {OFMT = "%.0f"} {print /1024,"MB", }'

0 MB ./etc
1 MB ./mail
2 MB ./tmp
123 MB ./public_html


#20 楼

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

#21 楼

如果需要处理空格,则可以使用以下内容

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


附加的sed语句将有助于减轻诸如应用程序支持之类名称的文件夹的问题

评论


刚刚在macOS Sierra上尝试过。可以正常工作。真好!

–心脏病学
17年7月19日在4:44

#22 楼

另一个awk解决方案-

du -k ./* | sort -nr | 
awk '
{split("KB,MB,GB",size,",");}
{x = 1;while ( >= 1024) 
{ =  / 1024;x = x + 1}  = sprintf("%-4.2f%s", , size[x]); print q4312078q;}'


[jaypal~/Desktop/Reference]$ du -k ./* | sort -nr | awk '{split("KB,MB,GB",size,",");}{x = 1;while ( >= 1024) { =  / 1024;x = x + 1}  = sprintf("%-4.2f%s", , size[x]); print q4312078q;}'
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


#23 楼

这是一个示例

du -h /folder/subfolder --max-depth=1 | sort -hr


返回值:

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


还可以添加| head -10来查找前10名或指定目录中任意数量的子文件夹。

#24 楼

Voilà:

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


#25 楼

http://dev.yorhel.nl/ncdu

命令:
ncdu

目录导航,排序(名称和大小),图形,人类可读的等...

评论


实用工具,但默认情况下未安装在我知道的任何操作系统上。不一定是问题,但是还要照顾另一个程序...

–voretaq7
2011年11月29日23:07

#26 楼

我一直在使用@ptman提供的解决方案,但是最近的服务器更改使其不再可行。取而代之的是,我使用以下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(<1024)
    printf("%.0f KB\t%s",,);
else if(<1024*1024)
    printf("%.1f MB\t%s",/1024,);
else
    printf("%.1f GB\t%s",/1024/1024,);
}'


评论


自从coreutils 8.6于2010年发布以来,GNU du就一直支持BSD du -d 1语法(尽管它的第一个Red Hat可用性是2014年的RHEL 7),所以您不再需要--maxdepth = 1。我最近才才发现这一点。

–亚当·卡兹(Adam Katz)
17年5月3日在21:47

#27 楼


du -s * |排序-nr |切-f2 | xargs du -sh


评论


那不是一个很好的解决方案,因为它两次遍历文件系统。

– Paul Gear
2015年9月30日下午0:06

#28 楼

这里有很多答案,很多都是重复的。我看到了三种趋势:通过第二个du调用进行管道传输,使用复杂的shell / awk代码以及使用其他语言。

这是一个使用du和awk的POSIX兼容解决方案,该解决方案适用于每个系统。

我采取了一种略有不同的方法,添加了-x以确保我们保持在同一文件系统上(我只在磁盘空间不足时才需要执行此操作,所以为什么要清除掉我的东西?可以安装在此FS树中,还是向后移动并符号链接?),并显示常量单位,以便于视觉解析。在这种情况下,我通常选择不排序,以便更好地了解层次结构。

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


(由于这是一致的单位,因此可以在后面附加| sort -n您确实想要排序的结果。)

这会过滤出目录(累积内容)不超过512MB的所有目录,然后以GB为单位显示大小。默认情况下,du使用512字节的块大小(因此awk的220个块的条件是512MB,它的221除数将单位转换为GB —我们可以将du -kx > 512*1024s/1024^2结合使用,以便于人类阅读)。在awk条件内,我们将s设置为大小,以便可以从行(%s)中将其删除。这将保留定界符(将其折叠为单个空格),因此最后的%7s表示一个空格,然后表示聚合目录的名称。 %.2f对齐四舍五入后的%8s GB大小(如果大于10TB,则增加到q4312079q)。

与此处的大多数解决方案不同,此方法正确支持名称中带有空格的目录(尽管每个解决方案,包括该解决方案) ,将错误处理包含换行符的目录名称。

#29 楼

至少对于普通工具而言,这将是困难的,因为人类可读的数字所采用的格式(请注意,sort在对数字进行排序时做得很好,因为它对数字进行排序-508、64、61、2、2-只是不能用额外的乘数对浮点数进行排序。)

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

#30 楼

您可以尝试的是:

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


希望有所帮助。

评论


这就是xargs所做的;-)

– cadrian
09年2月25日在14:05

呵呵,我总是忘了xargs。 ;)归根结底,无论完成什么工作,imo都是如此。

–克里斯蒂安·威茨(Christian Witts)
09年2月25日在15:05

默认情况下,MacOSX(即在自制软件之外)不支持正确的xargs,因此此格式是必需的。但是,对于其中包含空格的文件,您需要设置IFS:IFS = $'\ n'

–汉卡
16年1月30日在11:16