关于linux:使用ls列出目录及其总大小

Using ls to list directories and their total sizes

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

1
2
3
4
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

在搜索了这些手册页后,我空洞地说。


尝试类似的东西:

1
du -sh *

简短版本:

1
du --summarize --human-readable *

说明:

du:磁盘使用情况

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

-h:"人类可读"的输出。使用单位后缀:Byte,Kibibyte(KiB),Mebibyte(MiB),Gibibyte(GiB),Tebibyte(TiB)和Pebibyte(PiB)。 (BASE2)


du -sk * | sort -n将按大小对文件夹进行排序。想要清理空间有帮助..


1
du -sh * | sort -h

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


以人类可读格式列出当前目录中的最大目录:

du -sh * | sort -hr

限制行数的更好方法是

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

您可以在其中增加-n标志的后缀以限制列出的行数

样品:

1
2
3
4
5
6
7
8
9
10
11
[~]$ 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 -lh格式显示,请使用:

1
(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代码解释说:

1
2
3
4
5
6
7
8
9
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
}

样本输出:

1
2
3
4
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


你想要的命令是'du -sk'du ="磁盘使用"

-k标志为您提供以千字节为单位的输出,而不是磁盘扇区的du默认值(512字节块)。

-s标志仅列出顶级目录中的内容(即默认情况下的当前目录或命令行中指定的目录)。在这方面,du具有相反的ls行为,这很奇怪。默认情况下,du将递归地为您提供每个子目录的磁盘使用情况。相反,ls只会在指定目录中提供列表文件。 (ls -R为您提供递归行为。)


将此shell函数声明放在shell初始化脚本中:

1
2
3
function duls {
    paste <( du -hs --"$@" | cut -f1 ) <( ls -ld --"$@" )
}

我将其称为duls,因为它显示了duls的输出(按此顺序):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$ 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 -ld --"$@"的输出作为第二个文件。

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

双精度(--)表示命令行选项结束为duls。如果没有这些,说duls -l会混淆du并且ls没有的du的任何选项会混淆ls(并且两个实用程序中存在的选项可能并不意味着相同的事情,并且它会很糟糕)。

du之后的cut简单地删除了du -hs输出的第一列(大小)。

我决定将du输出放在左边,否则我将不得不管理一个摇摆不定的右列(由于文件名的长度不同)。

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

这已经在bashksh93中进行了测试。它不适用于/bin/sh


我总是使用du -sk(-k标志显示文件大小,以千字节为单位)。


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


这是我喜欢的

更新:我不喜欢上一个,因为它没有在当前目录中显示文件,它只列出了目录。

ubuntu上/var的示例输出:

sudo du -hDaxd1 /var | sort -h | tail -n10

1
2
3
4
5
6
7
8
9
10
4.0K    /var/lock
4.0K    /var/run
4.0K    /var/www
12K     /var/spool
3.7M    /var/backups
33M     /var/log
45M     /var/webmin
231M    /var/cache
1.4G    /var/lib
1.7G    /var

du -sch *在同一目录中。


这些都是很好的建议,但我使用的是:

1
du -ksh * | sort -n -r

-ksh确保文件和文件夹以人类可读的格式列出,并以兆字节,千字节等为单位。然后您按数字排序并反转排序,以便将较大的文件和文件夹放在第一位。

这个命令的唯一缺点是计算机不知道技嘉大于兆字节,所以它只会按数字排序,你会经常找到这样的列表:

1
2
3
120K
12M
4G

小心看看单位。

此命令也适用于Mac(而sort -h不适用于此)。


看一下du命令


1
du -S

du有另一个有用的选项:-S, --separate-dirs告诉du不包括子目录的大小 - 在某些情况下很方便。

示例1 - 仅显示目录中的文件大小:

1
2
3
du -Sh  *
3,1G    10/CR2
280M    10

示例2 - 显示目录中的文件大小和子目录:

1
2
3
du -h  *
3,1G    10/CR2
3,4G    10


du -sm * | sort -nr

按大小输出


ncdu ncurses du

这个非常棒的CLI实用程序允许您以交互方式轻松查找大型文件和目录。

例如,从一个众所周知的项目的树内部我们做:

1
2
sudo apt-get install ncdu
ncdu

结果如下:

enter image description here

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

enter image description here

ncdu仅在启动时为整个树递归计算一次文件大小,因此效率很高。

"磁盘使用总量"与"表观大小"类似于du,我已经解释过:为什么`du`的输出通常与`du -b`有很大不同

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

相关问题:

  • https://unix.stackexchange.com/questions/67806/how-to-recursively-find-the-amount-stored-in-directory/67808
  • https://unix.stackexchange.com/questions/125429/tracking-down-where-disk-space-has-gone-on-linux
  • https://askubuntu.com/questions/57603/how-to-list-recursive-file-sizes-of-files-and-directories-in-a-directory
  • https://serverfault.com/questions/43296/how-does-one-find-which-files-are-taking-up-80-of-the-space-on-a-linux-webserve

在Ubuntu 16.04中测试过。

ncdu非交互式使用

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

例如,要生成文件运行:

1
ncdu -o ncdu.json

然后以交互方式检查它:

1
ncdu -f ncdu.json

如果您正在处理像NFS这样非常大且速度很慢的文件系统,那么这非常有用。

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

输出格式只是JSON,因此很容易将其重用于其他程序,例如:

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
[
    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中测试过。


只是一个警告,如果你想比较文件的大小。 du根据文件系统,块大小,...产生不同的结果。

可能发生文件的大小不同,例如,比较本地硬盘和USB大容量存储设备上的相同目录。我使用以下脚本,包括ls来总结目录大小。结果以字节为单位考虑所有子目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
echo"[GetFileSize.sh] target directory: "$1""

iRetValue=0

uiLength=$(expr length"$1")
if [ $uiLength -lt 2 ]; then
  echo"[GetFileSize.sh] invalid target directory: "$1" - exiting!"
  iRetValue=-1
else
  echo"[GetFileSize.sh] computing size of files..."

  # use ls to compute total size of all files - skip directories as they may
  # show different sizes, depending on block size of target disk / file system
  uiTotalSize=$(ls -l -R $1 | grep -v ^d | awk '{total+=$5;} END {print total;}')
  uiLength=$(expr length"$uiTotalSize")
  if [ $uiLength -lt 1 ]; then
    uiTotalSize=0
  fi
  echo -e"[GetFileSize.sh] total target file size: "$uiTotalSize""

fi

exit"$iRetValue"

嗯,最好的方法是使用这个命令:

1
du -h -x / | sort -hr >> /home/log_size.txt

然后,您将能够在所有服务器上获取所有大小的文件夹。轻松帮助您找到最大的尺寸。


以递归方式显示当前目录的文件和子目录大小:

1
du -h .

要显示相同大小的信息但不递归地打印它们的子目录(可能是一个巨大的列表),只需使用--max-depth选项:

1
du -h --max-depth=1 .


有一段时间,我使用Nautilus(在RHEL 6.0上的Gnome桌面上)删除我的主文件夹上的文件,而不是在bash中使用rm命令。结果,显示的总大小

1
du -sh

当我使用时,与每个子目录的磁盘使用量之和不匹配

1
du -sh *

我花了一段时间才意识到Nautilus将已删除的文件发送到其Trash文件夹,并且该文件夹未在du -sh *命令中列出。所以,只是想分享这个,以防有人遇到同样的问题。


我遇到了类似于Martin Wilde描述的问题,在我的情况下,在使用rsync镜像后比较两个不同服务器上的相同目录。

我没有使用脚本,而是将-b标志添加到du中,该标志以字节为单位计算大小,并且我可以确定消除了两台服务器上的差异。您仍然可以使用-s -h来获得可理解的输出。


以下是容易记住的

1
ls -ltrapR

list directory contents

-l use a long listing format

-t sort by modification time, newest first

-r, --reverse
reverse order while sorting

-a, --all
do not ignore entries starting with .

-p, --indicator-style=slash
append / indicator to directories

-R, --recursive
list subdirectories recursively

https://explainshell.com/explain?cmd=ls+-ltrapR


放在init脚本中,如.bashrc ...根据需要调整def。

1
2
3
4
5
6
duh() {
  # shows disk utilization for a path and depth level
  path="${1:-$PWD}"
  level="${2:-0}"
  du"$path" -h --max-depth="$level"
}

如果您想要更多地控制要列出目录的size,可以使用threshold(-t)开关,如下所示:

1
$ du -ht 1000000000 | sort --reverse

du - d isk u sage
h - 人类可读格式
t - 阈值大小

在这里,我们要列出大小超过1GB的所有目录。

1
$ du -ht 1G | sort --reverse

说明:

维基中描述的单位如下:

K, M, G, T, P, E, Z, Y (powers of 1024) or
KB, MB, GB, TB, PB, EB, ZB, YB (powers of 1000).


输入"ls -ltrh / path_to_directory"