使用ls列出目录及其总大小

1174

在Unix中,是否可以使用ls列出子目录及其所有内容的总大小,而不是通常的4K(我认为)只是目录文件本身的大小?

total 12K
drwxrwxr-x  6 *** *** 4.0K 2009-06-19 10:10 branches
drwxrwxr-x 13 *** *** 4.0K 2009-06-19 10:52 tags
drwxrwxr-x 16 *** *** 4.0K 2009-06-19 10:02 trunk

在查看了man手册后,我毫无头绪。


4
你想要使用"du -s"命令。 - guns
46
搜索鸭子:alias ducks='du -cksh * | sort -hr | head -n 15'。该命令将显示当前目录下占用磁盘空间最多的前15个文件或文件夹,并按照从高到低的顺序排列。 - Sebi
请注意,alias ducks='du -cksh * | sort -hr | head -n 15' 中的 -h 选项和 du-c 选项大多是非便携式 GNU 扩展,而不是 POSIX 标准 dusort 实用程序。如果没有 -h 选项,则必须使用 -n 选项调用 sort 进行数字排序,简化为:du -sk * | sort -n - Andrew Henle
sort中省略-r,并且不通过head(或tail)传递结果,将整个结果发送到终端,最大的结果最后显示。这在交互式会话中非常有用。请注意,*将跳过以.开头的文件和目录,例如.m2 - Andrew Henle
29个回答

2089
尝试以下内容:

尝试以下内容:

du -sh *

简单版:

du --summarize --human-readable *

解释:

du:磁盘使用情况。

-s:显示每个指定文件的摘要信息。(相当于-d 0

-h:“人类可读”输出。使用单位后缀:B(字节)、KiB(千字节)、MiB(兆字节)、GiB(吉字节)、TiB(太字节)和PiB(拍字节)。 (BASE2)


85
同时,-c(生成总计)也很好。 - meridius
63
du --max-depth 1 只显示树形结构中深度为 1 的文件/文件夹大小,没有多余的信息,方便查找文件夹内的大文件。 - CousinCocaine
21
如何同时包含隐藏文件? - Zack Braksa
10
在zsh中,你可以使用*(D)来匹配隐藏的(即以.开头的)文件和普通文件。在bash中,你可以使用*.[^.]*来匹配它们两个。 - Sebi
35
想要了解空间的去向,可以输入命令 du -sch * .[!.]* | sort -rh 进行排序输出。 若使用 Mac 系统,请先运行命令 brew install coreutils,然后再输入 du -sch * .[!.]* | gsort -rh - Guig
显示剩余5条评论

461

du -sk * | sort -n 将按照大小对文件夹进行排序。在需要释放空间时非常有帮助。

或者使用 du -sh * | sort -h 命令以人类可读的方式显示结果。


17
在命令后加上 | tail -r 可以按最大值优先排序。 - Phrogz
83
sort -rn可以将内容按照数字大小进行逆序排序。如果你只想显示前面几个结果,可以使用sort -rn | head -n 10命令。 - AgileTillIDie
21
sort -rhdu -cksh * 结合使用可以很好地对人类可读的单位进行排序。 - Sebi
1
很遗憾,在Mac上,@Sebi -h不是sort命令的有效参数。 - fIwJlxSzApHEZIl
2
为什么需要 -k?文档中写道:-k类似于--block-size=1K,这会影响精度吗? - Rutger Hofste
显示剩余2条评论

150
du -sh * | sort -h

这将以人类可读的格式显示。


6
sort -h 更多信息请参见:http://www.gnu.org/software/coreutils/manual/coreutils.html#sort-invocation。该命令主要用于排序 103K102M1.1G 等带有单位的数据。现在很多系统都支持该命令,但并非全部系统都支持。 - Evgeni Sergeev
duh -shm * | sort -n ? - std''OrgnlDave
14
非常好用,只需添加一个小细节du -sh * | sort -rh(-r表示按文件夹大小逆序排列)。 - artm
2
要包括隐藏的文件/目录; du -sh $(ls -A) | sort -h - jmd_dk
这个命令总是需要很长时间才能运行...有没有替代方案?这就是我在寻找像标题中带有ls的Q的原因。 - Charlie Parker

69

以易读的格式列出当前目录中最大的目录:

du -sh * | sort -hr

限制行数更好的方法是:

du -sh * | sort -hr | head -n10

可以增加-n标志的后缀来限制所列出的行数。

示例:

[~]$ du -sh * | sort -hr
48M app
11M lib
6.7M    Vendor
1.1M    composer.phar
488K    phpcs.phar
488K    phpcbf.phar
72K doc
16K nbproject
8.0K    composer.lock
4.0K    README.md

它使阅读更加方便 :)


这个命令在我的电脑上总是需要很长时间才能运行...有没有替代方案?这就是我为什么在寻找一个标题类似于“ls”的Q的原因。 - Charlie Parker

35

要以ls -lh格式显示它,请使用:

(du -sh ./*; ls -lh --color=no) | awk '{ if($1 == "total") {X = 1} else if (!X) {SIZES[$2] = $1} else { sub($5 "[ ]*", sprintf("%-7s ", SIZES["./" $9]), $0); print $0} }'

解析 Awk 代码:

if($1 == "total") { // Set X when start of ls is detected
  X = 1 
} else if (!X) { // Until X is set, collect the sizes from `du`
  SIZES[$2] = $1
} else {
  // Replace the size on current current line (with alignment)
  sub($5 "[ ]*", sprintf("%-7s ", SIZES["./" $9]), $0); 
  print $0
}

样例输出:

drwxr-xr-x 2 root     root 4.0K    Feb 12 16:43 cgi-bin
drwxrws--- 6 root     www  20M     Feb 18 11:07 document_root
drwxr-xr-x 3 root     root 1.3M    Feb 18 00:18 icons
drwxrwsr-x 2 localusr www  8.0K    Dec 27 01:23 passwd

有没有任何方法可以对这个输出进行排序?如果你在 Mac 上删除 --color=no,它会非常出色。 - fIwJlxSzApHEZIl
@anon58192932 你可以将输出导入到 sort --key=5,5h 中,以对第五列的“人类可读单位”进行排序。 - Sebi
返回 sort: stray character in field spec: invalid field specification 5,5h'`。有时我真的很讨厌 Mac =\ - fIwJlxSzApHEZIl
@anon58192932,你可以问一个关于Mac的问题,我相信会有人能够帮助你。这个问题被标记为GNU/[tag:linux]。 - Sebi
2
这个答案有没有保留颜色的方法? - Pablo Canseco
1
格式化结果:(du -sh ./*; ls -lh --color=no) | awk '{ if($1 == "total") {X = 1} else if (!X) {SIZES[$2] = $1} else { printf("%11s %4s %-6s %-6s %7s %3s %2s %5s %s\n", $1, $2, $3, $4, SIZES["./" $9], $6, $7, $8, $9) } }' | sort --key=5,5h - Michael SM

27

ncdu(ncurses du

这个非常棒的CLI工具可以帮助您交互式地查找大文件和目录(包括递归总大小)。

例如,从一个知名的开源项目的根目录内执行以下命令:

sudo apt install ncdu
ncdu

输出结果是:

enter image description here

然后,我在键盘上向下和向右键进入/drivers文件夹,看到:

enter image description here

ncdu仅对整个树进行递归文件大小计算一次,因此它非常高效。这样,当您移动到子目录内部时,不需要重新计算大小来确定磁盘占用。

"总磁盘使用量"与"表面大小"类比于du,我已经在这里解释过:为什么`du`的输出通常与`du -b`非常不同?

项目主页:https://dev.yorhel.nl/ncdu

相关问题:

在Ubuntu 16.04中测试。

Ubuntu列出根目录

你可能想要的是:

ncdu --exclude-kernfs -x /

where:

  • -x 停止文件系统障碍的交叉
  • --exclude-kernfs 跳过特殊的文件系统,如/sys

MacOS 10.15.5列出根目录

要正确地在该系统上列出根目录/,我还需要--exclude-firmlinks,例如:

brew install ncdu
cd /
ncdu --exclude-firmlinks

否则,由于链接的无限循环,可能是由于以下原因:https://www.swiftforensics.com/2019/10/macos-1015-volumes-firmlink-magic.html

我们为爱所学到的东西。

ncdu 非交互式用法

ncdu 的另一个很酷的功能是您可以先以 JSON 格式转储大小,然后再重复使用它们。

例如,要生成该文件,请运行:

ncdu -o ncdu.json

然后通过交互方式进行检查:

ncdu -f ncdu.json

如果你正在处理一个非常大而又慢速的文件系统(如NFS),这非常有用。

这样,你可以先只导出一次,这可能需要几个小时,然后浏览文件,退出,再次浏览等。

输出格式只是JSON,因此也很容易与其他程序重复使用,例如:

ncdu -o -  | python -m json.tool | less

揭示了一个简单的目录树数据结构:

[
    1,
    0,
    {
        "progname": "ncdu",
        "progver": "1.12",
        "timestamp": 1562151680
    },
    [
        {
            "asize": 4096,
            "dev": 2065,
            "dsize": 4096,
            "ino": 9838037,
            "name": "/work/linux-kernel-module-cheat/submodules/linux"
        },
        {
            "asize": 1513,
            "dsize": 4096,
            "ino": 9856660,
            "name": "Kbuild"
        },
        [
            {
                "asize": 4096,
                "dsize": 4096,
                "ino": 10101519,
                "name": "net"
            },
            [
                {
                    "asize": 4096,
                    "dsize": 4096,
                    "ino": 11417591,
                    "name": "l2tp"
                },
                {
                    "asize": 48173,
                    "dsize": 49152,
                    "ino": 11418744,
                    "name": "l2tp_core.c"
                },

在Ubuntu 18.04上进行了测试。


1
太棒了。感谢分享! - Frank Fu
我同意,ncdu是正确的选择...但你知道能否搜索JSON文件吗?也就是说,获取特定文件/文件夹的完整路径。 - FGV
1
@FGV 我认为ncdu无法输出那个,一个可能的方法是编写一个简单的Python脚本来解析JSON。 - Ciro Santilli OurBigBook.com
我想说的话,和平。 - kakadais

21
将此 shell 函数声明放入您的 shell 初始化脚本中:
function duls {
    paste <( du -hs -- "$@" | cut -f1 ) <( ls -ldf -- "$@" )
}

我称它为 duls,因为它显示了来自 duls 的输出(按顺序):

$ duls
210M    drwxr-xr-x  21 kk  staff  714 Jun 15 09:32 .

$ duls *
 36K    -rw-r--r--   1 kk  staff    35147 Jun  9 16:03 COPYING
8.0K    -rw-r--r--   1 kk  staff     6962 Jun  9 16:03 INSTALL
 28K    -rw-r--r--   1 kk  staff    24816 Jun 10 13:26 Makefile
4.0K    -rw-r--r--   1 kk  staff       75 Jun  9 16:03 Makefile.am
 24K    -rw-r--r--   1 kk  staff    24473 Jun 10 13:26 Makefile.in
4.0K    -rw-r--r--   1 kk  staff     1689 Jun  9 16:03 README
120K    -rw-r--r--   1 kk  staff   121585 Jun 10 13:26 aclocal.m4
684K    drwxr-xr-x   7 kk  staff      238 Jun 10 13:26 autom4te.cache
128K    drwxr-xr-x   8 kk  staff      272 Jun  9 16:03 build
 60K    -rw-r--r--   1 kk  staff    60083 Jun 10 13:26 config.log
 36K    -rwxr-xr-x   1 kk  staff    34716 Jun 10 13:26 config.status
264K    -rwxr-xr-x   1 kk  staff   266637 Jun 10 13:26 configure
8.0K    -rw-r--r--   1 kk  staff     4280 Jun 10 13:25 configure.ac
7.0M    drwxr-xr-x   8 kk  staff      272 Jun 10 13:26 doc
2.3M    drwxr-xr-x  28 kk  staff      952 Jun 10 13:26 examples
6.2M    -rw-r--r--   1 kk  staff  6505797 Jun 15 09:32 mrbayes-3.2.7-dev.tar.gz
 11M    drwxr-xr-x  42 kk  staff     1428 Jun 10 13:26 src

$ duls doc
7.0M    drwxr-xr-x  8 kk  staff  272 Jun 10 13:26 doc

$ duls [bM]*
 28K    -rw-r--r--  1 kk  staff  24816 Jun 10 13:26 Makefile
4.0K    -rw-r--r--  1 kk  staff     75 Jun  9 16:03 Makefile.am
 24K    -rw-r--r--  1 kk  staff  24473 Jun 10 13:26 Makefile.in
128K    drwxr-xr-x  8 kk  staff    272 Jun  9 16:03 build

解释:

paste 实用程序根据您给出的规范从其输入中创建列。给定两个输入文件,它们并排放置,以制表符作为分隔符。

我们将 du -hs -- "$@" | cut -f1 的输出作为第一个文件(实际上是输入流),将 ls -ldf -- "$@" 的输出作为第二个文件。

在函数中,"$@" 将计算所有命令行参数的列表,每个参数都在双引号中。因此,它将理解通配符字符和带有空格等路径名。

双破折号(--)表示命令行选项的结束,适用于 duls。如果没有这些选项,则说 duls -l 会混淆 du,而任何 ls 没有的 du 选项也会混淆 ls(同时存在于两个实用程序中的选项可能意味着不同的事情,这将是一种混乱)。

du后面的cut命令会简单地剪切掉du -hs输出的第一列(文件大小)。

我决定把du的输出放在左边,否则我就得处理一个不稳定的右列(由于文件名长度不同而导致)。

该命令不接受命令行标志。

这已经在bashksh93中进行了测试。它将无法在/bin/sh中工作。


很好。权限和大小在同一行。 - Ben
我一直在使用hack paste <(echo ""; du -sh $(ls) | cut -f 1) <(ls -l) - Mateen Ulhaq
请注意,这通常无法处理非默认排序的输入,例如“duls $(ls -tr)”。 - Mateen Ulhaq
@MateenUlhaq,只需在我的代码中调用ls时添加-f即可轻松解决这个问题。你提出的命令很可能会遇到包含空格、制表符或换行符的任何文件名以及以破折号开头的名称的问题。 - Kusalananda

21

你需要的命令是 'du -sk'。du代表"磁盘使用情况"。

使用-k选项可以将输出以千字节为单位显示,而不是默认的磁盘扇区(每个扇区为512字节)。

使用-s选项只会列出顶层目录中的内容(默认为当前目录,或者在命令行中指定的目录)。奇怪的是,du在这方面与ls相反。默认情况下,du会递归地给出每个子目录的磁盘使用情况。相比之下,ls只会列出指定目录中的文件。(ls -R会递归地列出子目录。)


尝试在根目录上执行此操作,但仍会尝试列出子目录,导致产生大量消息。 - Nagev

18

按照大小排序(从大到小)的文件和文件夹向下有序列表,其所在目录为:

du -skh * | sort -hr

包括隐藏文件:

du -skh .??* * | sort -hr

解释:

du 命令用于预估磁盘空间的使用情况。

  • -s 汇总,即只计算当前级别下的文件/文件夹,不包括子目录。
  • -kh 以人类可读的方式显示大小,如GB、MB、KB等。
  • .??* 文件名以点“.”开头且长度大于3个字符(不包括“.”和“..”链接)。
  • * 所有不以点“.”开头的文件/文件夹。

du 默认按较小的文件大小排列。由于我们需要调用两组文件(隐藏和正常),所以需要再次使用 sort 命令将结果合并。

  • -h 以人类可读的字符重新排序(人类数字,如GB、MB等)。
  • -r 反向排序。

注意:其他答案包含了大部分这些选项,但它们散布在不同的地方,本文还介绍了如何轻松包含隐藏的文件/文件夹。


10
du -h --max-depth=1 . | sort -n -r

2
使用“du -h -d 1”命令,最大深度为1。简写形式。 - possumkeys
1
du -hd1是du命令的简写形式 ;) - kakadais
$ du -h -d 1 完美,谢谢。 - vintagexav

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接