所以,在很多情况下我想知道我的磁盘空间占用了多少,所以我知道要摆脱什么,转换成另一种格式,存储在别处(如数据DVD),转移到另一个分区等。在这种情况下,我正在查看SliTaz Linux可启动媒体的Windows分区。
在大多数情况下,我想要的是文件和文件夹的大小,为此我使用基于NCurses的ncdu:
但在这种情况下,我想要一种方法来获得 所有匹配正则表达式 的文件的大小。 .bak文件的示例正则表达式:
.*\.bak$
如何考虑使用核心GNU实用程序或BusyBox的标准Linux,我如何获取该信息?
编辑:输出旨在由脚本解析。
答案 0 :(得分:43)
我建议像:find . -regex '.*\.bak' -print0 | du --files0-from=- -ch | tail -1
一些注意事项:
-print0
的{{1}}选项和find
的{{1}}可以避免文件名中的空白问题--files0-from
,而不仅仅是du
,所以如果你修改它,请考虑到这一点./dir1/subdir2/file.bak
标志来生成“人类可读”的格式,但是如果要解析输出,最好使用file.bak
(总是使用千字节)h
命令,您还将看到特定文件和目录的大小Sidenote:一个很好的GUI工具,可以找出谁占用你的磁盘空间FileLight。它没有正则表达式,但是非常方便查找阻塞磁盘的大目录或文件。
答案 1 :(得分:22)
du
是我最喜欢的答案。如果您有固定的文件系统结构,则可以使用:
du -hc *.bak
如果您需要添加子目录,只需添加:
du -hc *.bak **/*.bak **/**/*.bak
等等
但是,这不是一个非常有用的命令,所以使用你的find:
TOTAL=0;for I in $(find . -name \*.bak); do TOTAL=$((TOTAL+$(du $I | awk '{print $1}'))); done; echo $TOTAL
这将回显您找到的所有文件的总大小(以字节为单位)。
希望有所帮助。
答案 2 :(得分:3)
在Bourne Shell中运行此命令以声明一个函数,该函数计算当前目录中与正则表达式模式匹配的所有文件的大小总和:
sizeofregex() { IFS=$'\n'; for x in $(find . -regex "$1" 2> /dev/null); do du -sk "$x" | cut -f1; done | awk '{s+=$1} END {print s}' | sed 's/^$/0/'; unset IFS; }
(或者,您可以将其放在脚本中。)
<强>用法:强>
cd /where/to/look
sizeofregex 'myregex'
结果将是一个数字(以KiB为单位),包括0
(如果没有与您的正则表达式匹配的文件)。
如果您不希望它在其他文件系统中查找(假设您要查找.so
下的所有/
个文件,这是/dev/sda1
的挂载,但不在/home
下{1}},/dev/sdb1
的附加内容,在上面的函数中向-xdev
添加find
参数。
答案 3 :(得分:3)
之前的解决方案对我来说无法正常工作(我遇到了管道问题du
),但以下方法效果很好:
find path/to/directory -iregex ".*\.bak$" -exec du -csh '{}' + | tail -1
iregex
选项是不区分大小写的正则表达式。如果您希望区分大小写,请使用regex
。
如果您对正则表达式不满意,可以使用iname
或name
标志(前者不区分大小写):
find path/to/directory -iname "*.bak" -exec du -csh '{}' + | tail -1
如果您想要每个匹配的大小(而不仅仅是合计的总数),只需省略管道尾命令:
find path/to/directory -iname "*.bak" -exec du -csh '{}' +
这些方法避免了@MaddHackers回答中的子目录问题。
希望这可以帮助处于相同情况的其他人(在我的情况下,查找.NET解决方案中所有DLL的大小)。
答案 4 :(得分:1)
如果你对glob-patterns没问题,而你只对当前目录感兴趣:
stat -c "%s" *.bak | awk '{sum += $1} END {print sum}'
或
sum=0
while read size; do (( sum += size )); done < <(stat -c "%s" *.bak)
echo $sum
stat的%s
指令给出字节而不是千字节。
如果您希望使用bash版本4进入子目录,可以shopt -s globstar
并使用模式**/*.bak
答案 5 :(得分:1)
接受的回复建议使用
find . -regex '.*\.bak' -print0 | du --files0-from=- -ch | tail -1
但由于du
在我的系统上不知道--files-0-from
选项,因此无法在我的系统上运行。只有GNU du
知道该选项,它既不是POSIX Standard的一部分(所以你不能在FreeBSD或macOS中找到它),你也不会在{{3}找到它(例如,大多数嵌入式Linux系统)或任何其他不使用GNU du
版本的Linux系统。
然后有回复建议使用:
find path/to/directory -iregex .*\.bak$ -exec du -csh '{}' + | tail -1
只要找不到太多文件,此解决方案就可以正常运行,因为+
表示find
会尝试使用尽可能多的点击来调用du
但是,单个调用可能存在系统支持的最大参数数量(N),如果命中数超过此值,find
将多次调用du
,将命中数分成较小的组大于或等于每个N项,这种情况下结果将是错误的,只显示最后du
次呼叫的大小。
最后有一个使用stat
和awk
的答案,这是一个很好的方法,但它依赖于shell globbing,只有Bash 4.x或更高版本支持。它不适用于旧版本,如果它与其他shell一起使用是不可预测的。
POSIX一致性解决方案(适用于Linux,macOS和任何BSD变体),不会受到任何限制,并且肯定适用于每个shell:
find . -regex '.*\.bak' -exec stat -f "%z" {} \; | awk '{s += $1} END {print s}'