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在最后给出总数。
小智 30
以下功能可以完成您所要求的大部分工作:
dir () { ls -FaGl "${@}" | awk '{ total += $4; print }; END { print total }'; }
Run Code Online (Sandbox Code Playgroud)
...但它不会给你你想要的东西dir -R *.jpg *.tif,因为那不是这样的ls -R。您可能想为此使用该find实用程序。
小智 8
只需打印您正在求和的当前行:
dir | awk '{ print; total += $4 }; END { print "total size: ",total }'
Run Code Online (Sandbox Code Playgroud)
使用 perl:
perl -le 'map { $sum += -s } @ARGV; print $sum' -- *.pdf
Run Code Online (Sandbox Code Playgroud)
当前目录中所有非隐藏 PDF 文件的大小。
为了使用掩码计算目录中的文件,我倾向于遵循以下方法:
对于字节
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)
你明白了。
分解很简单:
total如果还没有初始化变量,并添加由 分隔的第一个块field separator,在本例中为 a space character。这可以通过-F标志来改变。awk使用它在一行中放置多个语句,类似于终止 linux 命令行语句。否则,您可以将它们放在仍被 { ... } 包围的多行内容中awk将在退出之前执行指定的操作。因此,在我们想要计算目录中 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)