我怎样才能得到标准输入的大小?

str*_*gee 9 size pipe disk-usage files stdin

我将要压缩一个大目录,我想知道生成的文件究竟有多大。

我试过使用du

$ tar -cv dir | du -h -
du: cannot access '-': No such file or directory
Run Code Online (Sandbox Code Playgroud)

然后我尝试使用'-'的文件版本:

$ tar -cv dir | du -h /dev/stdin
1.0K
Run Code Online (Sandbox Code Playgroud)

我确定这个数字不准确。我怎样才能得到标准输入的大小?

str*_*gee 11

tl;博士tar -cv dir | wc -c - | cut -d' ' -f 1 | awk '{print $1/1000"K"}'

du实际上并不计算文件本身的大小。它只是要求内核查询已经跟踪文件大小的文件系统。这就是为什么它这么快。正因为如此,而且您计算的是流而不是文件这一事实是du行不通的。我的猜测是这1.0K/dev/std*内核中的硬编码大小。

解决方案是使用wc -c,它自己计算字节数而不是查询内核:

$ tar -cv dir | wc -c
Run Code Online (Sandbox Code Playgroud)

如果你想要类似的输出du -h

$ tar -cv dir | wc -c | awk '{print $1/1000"K"}'
Run Code Online (Sandbox Code Playgroud)

awk圈数成的人类可读的结果。

  • 请注意,如果您只是省略了 `wc` 多余的 `-`,那么您也不需要后续的 `cut` 命令。 (10认同)

Jan*_*nis 7

我建议:

tar cf - dir | wc -c
Run Code Online (Sandbox Code Playgroud)

一个简单的c(不需要前导-)用于创建tar存档,f指定一个输出文件并-表示它是stdout。(请注意,如果您只需要大小并且dir下有许多文件,出于性能原因,您可能宁愿省略tar's v。)


mik*_*erv 7

使用 GNU,tar您可以执行以下操作:

tar --totals -c . >/dev/null
Run Code Online (Sandbox Code Playgroud)

...这将呈现输出如...

Total bytes written: 5990400 (5.8MiB, 5.5GiB/s)
Run Code Online (Sandbox Code Playgroud)

...在标准错误上。同样,您可以使用任何 tar (或流)dd来提供有关字节计数的报告。这可能比 更可取wc,也可能不更可取,但dd默认为 512 字节的块大小 - 这与tar的块大小相同。如果您系统的PIPE_BUF足够大,您甚至可以扩展dd的块大小以匹配tar的记录大小 - 即 20 个块或 10240 字节。像这样:

tar -c . | dd bs=bx20 >/dev/null
585+0 records in
585+0 records out
5990400 bytes (6.0 MB) copied, 0.0085661 s, 699 MB/s
Run Code Online (Sandbox Code Playgroud)

这可能会也可能不会提供比wc.

不过,在 theddtaruse-cases 中,您实际上不需要处理流。我重定向到/dev/null上面 - 但我可以很容易地重定向到某个文件,并且在编写时仍然收到有关其大小的报告。


小智 6

我会选择@strugee的答案,但我将使用numfmt工具,该工具专为内存单位转换而设计,并支持许多选项:

tar cf - dir | wc -c | numfmt --to=si
Run Code Online (Sandbox Code Playgroud)

--to=si将以 SI 单位显示输出(例如:4M 表示 4000000 字节)。如果您更喜欢所谓的“二进制”单位,请忽略--iec-i(例如:4Mi 表示 4194304 字节)。