在目录列表中显示文件大小的总和

Mat*_*DMo 94 ls bash awk shell-script

Windowsdir目录列表命令的末尾有一行显示列出的文件占用的空间总量。例如,dir *.exe显示.exe当前目录中的所有文件、它们的大小以及它们的总大小。我很想dir在 bash 中为我的别名提供类似的功能,但我不确定如何去做。

目前,我alias dir='ls -FaGl'在我的.bash_profile, 显示

drwxr-x---+  24 mattdmo  4096 Mar 14 16:35 ./
drwxr-x--x. 256 root    12288 Apr  8 21:29 ../
-rw-------    1 mattdmo 13795 Apr  4 17:52 .bash_history
-rw-r--r--    1 mattdmo    18 May 10  2012 .bash_logout
-rw-r--r--    1 mattdmo   395 Dec  9 17:33 .bash_profile
-rw-r--r--    1 mattdmo   176 May 10  2012 .bash_profile~
-rw-r--r--    1 mattdmo   411 Dec  9 17:33 .bashrc
-rw-r--r--    1 mattdmo   124 May 10  2012 .bashrc~
drwx------    2 mattdmo  4096 Mar 24 20:03 bin/
drwxrwxr-x    2 mattdmo  4096 Mar 11 16:29 download/
Run Code Online (Sandbox Code Playgroud)

例如。从这个问题中得到答案:

dir | awk '{ total += $4 }; END { print total }'
Run Code Online (Sandbox Code Playgroud)

这给了我总数,但不打印目录列表本身。有没有办法将其更改为单行脚本或 shell 脚本,以便我可以传递ls我想要的任何参数dir并获得完整列表加上总和?例如,我想运行dir -R *.jpg *.tif以获取所有子目录中这些文件类型的列表和总大小。理想情况下,如果我能获得每个子目录的大小就太好了,但这不是必需的。

小智 208

已经有一个用于此的 UNIX 命令: du

做就是了:

du -ach 
Run Code Online (Sandbox Code Playgroud)

按照惯例,您可以在命令末尾添加一个或多个文件或目录路径。-h是将大小转换为人性化格式的扩展,-a为您提供“表观”大小(文件大小而不是磁盘使用情况),并-c在最后给出总数。

  • 是的,du 工作正常。您可以使用 -c 选项(与 --total 相同)来获取列表末尾的总数。 (15认同)
  • 请注意,`du` 给出了磁盘使用情况,而不是文件大小的总和。 (13认同)
  • !`-a` 的意思是 `--all`。考虑使用`--apparent-size` (10认同)
  • `du -h` 不会对传递给它的文件的大小求和。`du -h *.so` 显示每个文件的大小,但不显示总和。我认为你在这里想要的是`du -hc *.so`(甚至`du -hc *.so | tail -1`)。但当然,他也想要目录列表。 (8认同)

小智 30

以下功能可以完成您所要求的大部分工作:

dir () { ls -FaGl "${@}" | awk '{ total += $4; print }; END { print total }'; }
Run Code Online (Sandbox Code Playgroud)

...但它不会给你你想要的东西dir -R *.jpg *.tif,因为那不是这样的ls -R。您可能想为此使用该find实用程序。

  • `dir` 已经是一个流行的 GNU coreutil 的名称,我不想这样命名一个函数。 (3认同)

小智 29

您可以使用 du -h -c directory|tail -1

这将生成一行内存使用情况。

  • `du -hs directory` 如果你只想要总数。 (21认同)

小智 8

只需打印您正在求和的当前行:

dir | awk '{ print; total += $4 }; END { print "total size: ",total }'
Run Code Online (Sandbox Code Playgroud)


ing*_*ngo 8

使用 perl:

perl -le 'map { $sum += -s } @ARGV; print $sum' -- *.pdf
Run Code Online (Sandbox Code Playgroud)

当前目录中所有非隐藏 PDF 文件的大小。


Bar*_*man 5

为了使用掩码计算目录中的文件,我倾向于遵循以下方法:

对于字节

du -ac --bytes  | grep "zip$" | awk '{ print; total += $1 }; END { print "total lobsters: ", total, " Bytes" }'
Run Code Online (Sandbox Code Playgroud)

千字节

du -ac --bytes  | grep "zip$" | awk '{ print; total += $1 }; END { print "total lobsters: ", total/1024, " KB" }'
Run Code Online (Sandbox Code Playgroud)

对于兆字节

du -ac --bytes  | grep "zip$" | awk '{ print; total += $1 }; END { print "total lobsters: " total/1024/1024 " MB" }'
Run Code Online (Sandbox Code Playgroud)

你明白了。

分解很简单:

  • du - 磁盘使用情况
    • -a - 所有文件
    • -c - 总字节数
    • --bytes - 以字节为单位打印输出 [在较新版本的 bash 中,不确定这是否适用]
  • 的grep -叶形ř egular Ë XPRESSION p RINT [打印输出匹配的模式]
    • "zip$" - 要匹配的模式。“拉链”是字符串,并且字符串/线/等的“$”表示结束-在这种情况下,匹配线即END与“拉链”。相反,在该字符串的开头把“^”表示该模式将在字符串的开头[即:“^启动”将匹配行开始与词“开始”] -有了这些知识,包串分别在 ^ 和 $ 中,将匹配以使用的模式开始/结束的行。"^hello people$" 将匹配说 'hello people' 的字符串。"^hello(.*)people$" 将匹配字符串说 'hello french people' 和 'hello coding people',但不匹配'hello coding people with no life'
  • AWK -通过编程的脚本语言w ^ einbergerķ ernighan。不是一个非常原始的名称,而是一种非常强大的语言,非常适合文本处理和数据提取。
    • { 打印; 总计 += $1 }
      • 打印 - 打印当前正在迭代的行
      • total += $1 -total如果还没有初始化变量,并添加由 分隔的第一个块field separator,在本例中为 a space character。这可以通过-F标志来改变。
      • ; - 行/语句终止符。您可以awk使用它在一行中放置多个语句,类似于终止 linux 命令行语句。否则,您可以将它们放在仍被 { ... } 包围的多行内容中
      • END - 这实际上意味着awk将在退出之前执行指定的操作。
    • { 打印“总龙虾:”总“字节”}
      • 打印 "total lobsters: " - 输出字符串的第一部分
      • total - 包含迭代行总和的变量
      • “字节” - 打印字符串的最后一部分,附加到前两个语句的末尾
      • 显然,这三个语句和第一部分一样被封装在 { } 中。

因此,在我们想要计算目录中 zip 文件总数的情况下,逐步执行一个示例:

du -ac --bytes

836544  ./wp-content/themes/astra.1.8.1.zip
934364  ./wp-content/themes/astra.2.0.1.zip
400033  ./wp-content/uploads/2019/09/premium-addons-for-elementor-3.2.9-WJdFQT1mLd3GA81lQEAo.zip
117351218       ./wp-content/uploads/backwpup-fc5928-temp/2019-05-30_00-47-01_TX6FSKC601.zip
1192275 ./wp-content/plugins/essential-addons-elementor-master.zip
170     ./wp-content/plugins/gravityforms/images/doctypes/icon_zip.gif
1969651 ./wp-content/plugins/acf.zip
4284    ./wp-content/plugins/types/application/controllers/api/handler/import_from_zip_file.php
Run Code Online (Sandbox Code Playgroud)

输出的两个组成部分,col 1由数值表示:836544、934364...等,col 2是文件的路径。

但是,由于有两行与我们想要的不匹配 -icon_zip.gif并且import_from_zip_file.php- 我们想排除这些。由于du没有提供通过扩展递归过滤的方法(我知道),我们使用过滤grep

grep "zip$"

这有效地将输出从du管道传输到它,并过滤zip结尾的行,消除我们不想要的两个记录:

836544  ./wp-content/themes/astra.1.8.1.zip
934364  ./wp-content/themes/astra.2.0.1.zip
400033  ./wp-content/uploads/2019/09/premium-addons-for-elementor-3.2.9-WJdFQT1mLd3GA81lQEAo.zip
117351218       ./wp-content/uploads/backwpup-fc5928-temp/2019-05-30_00-47-01_TX6FSKC601.zip
1192275 ./wp-content/plugins/essential-addons-elementor-master.zip
1969651 ./wp-content/plugins/acf.zip
Run Code Online (Sandbox Code Playgroud)

然后 awk 解析每一行,并将数字col 1存储在$1

我们得到这个:

836544  ./wp-content/themes/astra.1.8.1.zip
934364  ./wp-content/themes/astra.2.0.1.zip
400033  ./wp-content/uploads/2019/09/premium-addons-for-elementor-3.2.9-WJdFQT1mLd3GA81lQEAo.zip
117351218       ./wp-content/uploads/backwpup-fc5928-temp/2019-05-30_00-47-01_TX6FSKC601.zip
1192275 ./wp-content/plugins/essential-addons-elementor-master.zip
1969651 ./wp-content/plugins/acf.zip
total lobsters:  128.339  MB
Run Code Online (Sandbox Code Playgroud)