パンツ*_*パンツ 4 command-line files disk-usage ls awk
我试图以精确的字节数找到硬盘驱动器上文件的大小,但是每当大小变得太大时,数字就会变得很奇怪(例如 1.98329e+12)。我可以阻止它这样做或将其转换为精确的字节吗?
命令是:
ls -lR | grep -v '^d' | awk '{total += $5} END {print "Total:", total}'
Run Code Online (Sandbox Code Playgroud)
确切字节的图片:

奇怪号码图片:

du -sb无论目录有多大,该命令都会正确显示确切的字节。ntfs这样的,所以我尝试将其格式化为 ext4 并复制我的文件。结果与ntfs相同。问题是 MAWK(安装在 Ubuntu 上的 AWK 变体)默认以科学计数法打印大于2147483647(2 31 -1) 的整数:
% awk -W version
mawk 1.3.3 Nov 1996, Copyright (C) Michael D. Brennan
compiled limits:
max NF 32767
sprintf buffer 2040
% printf '2147483647\n' | awk '{x += $1; print x}'
2147483647
% printf '2147483648\n' | awk '{x += $1; print x}'
2.14748e+09
Run Code Online (Sandbox Code Playgroud)
您可以使用printf格式说明符而不是print*:
printf '2147483648\n' | awk '{x += $1; printf "%.0f\n", x}'
Run Code Online (Sandbox Code Playgroud)
% printf '2147483648\n' | awk '{x += $1; printf "%.0f\n", x}'
2147483648
Run Code Online (Sandbox Code Playgroud)
在你的情况下:
ls -lR | grep -v '^d' | awk '{total += $5} END {printf "Total:%.0f\n", total}'
Run Code Online (Sandbox Code Playgroud)
ls -lR |
grep -v '^d' |
awk '
{
total += $5
}
END {
printf "Total:%.0f\n", total
}
'
Run Code Online (Sandbox Code Playgroud)
这将强制 AWK 以total十进制记数法而不是科学记数法打印。
但是,另一方面,您永远不应该解析ls.
一种更敏感的方法是使用find+ stat:
find . -type f -exec stat -c '%s' {} + | awk '{total += $1} END {printf "Total:%.0f\n", total}'
Run Code Online (Sandbox Code Playgroud)
find . -type f -exec stat -c '%s' {} + |
awk '
{
total += $1
}
END {
printf "Total:%.0f\n", total
}
'
Run Code Online (Sandbox Code Playgroud)
*%.0f是一种使printf打印数字大于2147483647(2 31 -1)的技巧,当%d用作格式说明符时,它总是打印为2147483647. 的限制%.0f是在9007199254740992(2 53 )之后将开始失去精度,如果这是一个问题(感谢 Rotsor 提供有用的信息)。
TL;DR:ls并且awk对于您的目的来说是不必要的。在要分析的目录上使用du -cb或du -bs。
你的目的是
所有这些操作都可以通过du.
$ du -bs $HOME 2>/dev/null
76709521942 /home/xieerqi
Run Code Online (Sandbox Code Playgroud)
值得注意的是,它du有两种“模式”——它可以显示文件的大小或它占用的实际磁盘空间(真实的物理空间)。由于您对所有文件的总大小感兴趣,因此您需要明显的文件大小。-b标志准确地给出了(-b是 的别名--apparent-size --block-size=1)。
也许更简洁和适当的解决方案是du -bc直接在您想要的目录上使用。例如,我的主目录大小约为 76 GB
$ du -bc $HOME 2> /dev/null | tail -1
76694582570 total
Run Code Online (Sandbox Code Playgroud)
出于某种原因,您担心文件夹大小和文件大小的差异。您在评论中说:
我更喜欢 ls 因为目录大小不同而文件大小不变
du是递归的,并总结文件大小。此外,目录确实具有 4096 字节(4k)的静态大小,但du它将包含在du -bs directory_name. 考虑一下:
$ du -b suse/openSUSE-Leap-42.1-DVD-x86_64.iso
4648337408 suse/openSUSE-Leap-42.1-DVD-x86_64.iso
$ du -b suse/
4648341504 suse/
$ bc <<< "4648337408+4096"
4648341504
$ mkdir suse/another_dir
$ du -b suse/another_dir
4096 suse/another_dir
$ du -bs suse/
4648345600 suse/
Run Code Online (Sandbox Code Playgroud)