检查一个tar gz文件的总内容大小

81

如何从命令行中提取.tar.gz文件中总未压缩的文件数据大小?


3
从一个Shell脚本中,使用Java、C、C++、C#中的哪种语言? - Jon Skeet
2
抱歉表述不够清晰,我指的是通过命令行 shell。 - Ztyx
7个回答

84

这适用于任何文件大小:

zcat archive.tar.gz | wc -c

对于小于4GB的文件,您还可以使用-l选项与gzip一起使用:

$ gzip -l compressed.tar.gz
     compressed        uncompressed  ratio uncompressed_name
            132               10240  99.1% compressed.tar

2
这给了我tar文件的大小,包括文件元数据,如文件名等。我正在寻找一种仅检查文件总大小的方法。无论如何,似乎唯一的方法是提取tar文件并在提取的内容上运行脚本。 - Ztyx
1
实际上,这可能已经足够了。您还需要为文件系统中不同的文件夹inode留出空间。此外,使用计算实际大小的 tar -tf... 命令将在完整文件上运行 gzip -d,因此您实际上会提取tar文件。此处所述的 gzip -l 不会提取文件,因此速度非常快。 - Vadim Fint
2
在我的情况下,这使我得到的未压缩大小比已压缩大小小,而且比率为负。 - lefterav
45
值得注意的是,报告的未压缩大小对2的32次方取模,这意味着对于大于4GB的文件无法正常工作。请改用以下命令:zcat archive.tar.gz | wc -c - nedned
3
谢谢 @nedned。我想知道一个大小为2.9GB的tar.gz文件中装满了文本数据文件,为什么会报告-36%的压缩比 o_O。这看起来像是一个愚蠢的错误。 - naught101
显示剩余2条评论

44

这将计算所提取文件的总内容大小:

$ tar tzvf archive.tar.gz | sed 's/ \+/ /g' | cut -f3 -d' ' | sed '2,$s/^/+ /' | paste -sd' ' | bc

输出的单位是字节(bytes)。

解释: tar tzvf 以详细格式列出存档文件中的文件,类似于 ls -l。使用 sedcut 分离出文件大小字段。第二个 sed 在每个大小前面放置一个 +,除了第一个之外,然后使用 paste 连接它们,得到一个求和表达式,由 bc 进行计算。

请注意,这不包括元数据,因此当您提取文件时占用的磁盘空间将会更大-如果您有许多非常小的文件,则可能会比实际大小大很多倍。


33
更简洁地说,tar tzvf archive.tar.gz | awk '{s+=$3} END{print (s/1024/1024), MB}' 的意思是:列出 archive.tar.gz 压缩文件中所有文件的详细信息,并使用 awk 工具计算文件大小总和,最后以兆字节 (MB) 为单位输出。 - Rubens
谢谢,Rubens。这很完美也很简单。我为我的项目做了这个,效果很好:tar tzvf 20180731.tar.gz | awk '{s+=$3} END{print (s/1024/1024/1024) " GB"}'。我不得不在“MB”或“GB”周围加上引号才能打印出来。 - Tony B
计算顶级目录(和文件)的大小:tar tzvf /tmp/root.tgz | sed 's/ +/ /g' | cut -f3,6- -d' ' | cut -f1 -d'/' | awk '{ arr[$2]+=$1 } END { for (key in arr) printf("%s\t%s\n", key, arr[key]) }' - Ilya Sheershoff
我看到了大小为0,0的情况,这会破坏管道。添加一个额外的sed 's / ./,/ g'会有所帮助。这将逗号替换为点,然后就可以进行求和。 - falkb
@Rubens 这是最好的答案。OP 想知道文件在 tar 中的大小,而不是解压后的大小,因为可能会出现 tar: Unexpected EOF in archive 的错误。 - Smeterlink

33

gzip -l archive.tar.gz命令在文件大小大于2GB时无法正常工作。我建议对于非常大的文件,使用zcat archive.tar.gz | wc --bytes代替。


2
我相信 gzip -l 在文件大小大于 4GB 时无法工作,因为 gzip 只使用 4 个字节来存储原始文件大小。 - kevin
1
在查看gzip.c的源代码时,它似乎是一个off_t,这是一个有符号的4字节值,因此最大值为2GB。 - swdev
6
gzip规范(https://www.ietf.org/rfc/rfc1952.txt)指出ISIZE字段应该是原始文件大小对2的32次幂取模的结果,不确定为什么gzip使用了有符号整数。 - kevin
1
列出大于4 GiB的文件已在gzip 1.12(2022-04)中得到修复,发行说明 - Fofola

11

我知道这是一个旧的答案,但是两年前我写了一个工具专门为此而设计。它叫做gzsize,它可以在不实际解压整个文件的情况下给出gzip文件的未压缩大小:

$ gzsize <your file>

它相比于将内容传输到“wc”有什么改进?我认为管道也可以实时工作。 - mxmlnkn
@mxmlnkn 至少快了两倍,有时甚至更快。在两个不同压缩级别的样本文件(一个是随机数据 - 压缩后11GB; 一个是重复数据 - 压缩后18MB)上,zcat|wc -l 花费了60秒和42秒,而 gzsize 则只花费了29秒和15秒。 - bfontaine

6
使用以下命令:
tar -xzf archive.tar.gz --to-stdout|wc -c

3

我在网上找到了很多站点,但是无法解决文件大小大于4GB时获取文件大小的问题。

首先,哪个更快?

[oracle@base tmp]$ time zcat oracle.20180303.030001.dmp.tar.gz | wc -c
    6667028480
real 0m45.761s user 0m43.203s sys 0m5.185s
[oracle@base tmp]$ time gzip -dc oracle.20180303.030001.dmp.tar.gz | wc -c
    6667028480
real 0m45.335s user 0m42.781s sys 0m5.153s
[oracle@base tmp]$ time tar -tvf oracle.20180303.030001.dmp.tar.gz
    -rw-r--r-- oracle/oinstall 111828 2018-03-03 03:05 oracle.20180303.030001.log
    -rw-r----- oracle/oinstall 6666911744 2018-03-03 03:05 oracle.20180303.030001.dmp

    real    0m46.669s
    user    0m44.347s
    sys     0m4.981s

显然,tar -xvf是最快的,但是如何在获取头部之后取消执行呢?

我的解决方案是这样的:

[oracle@base tmp]$  time echo $(timeout --signal=SIGINT 1s tar -tvf oracle.20180303.030001.dmp.tar.gz | awk '{print $3}') | grep -o '[[:digit:]]*' | awk '{ sum += $1 } END { print sum }'
    6667023572
real 0m1.005s user 0m0.013s sys 0m0.066s

头文件?你的解决方案完全依赖于文件大小和文件数量,这是有偏差的。请尝试对存档中的多个文件进行测试,而不是只有两个文件。同时,请尝试对更小和更大的tar.gz文件进行测试。 - B. Shea

-2

tar文件只有在通过其他程序(如gzip、bzip2、lzip、compress、lzma等)过滤后才会被解压缩。tar文件的文件大小与提取的文件相同,可能只添加了不到1kb的头信息以使其成为有效的tarball。


5
每个tar包中的每个文件都有512字节的标题,此外内部文件会被填充到512字节的倍数。这导致平均情况下每个tar包内的文件增加768字节的开销。 - Sarah G
tarballs 的作用就像 zip 文件一样,它们是用于传输的较小版本。 - Nate T
@Nathan 不是这样的。相反,它被设计成具有更大的数据块作为平均文件系统。TAR代表磁带归档,现在被重新用于更大的数据块的存档文件。实际上与传输无关,当它被设计时,调制解调器进行压缩。您可以像对任何其他文件一样gzip TAR。Tom的答案将给出非常无用的大小近似值,但这是相同的方法和从“gzip -l”答案获得的相同大小,而这些答案有66和27票,而Tom却遭到了负面评价?不公平。 - papo
@papo 我原来的评论措辞不当,但答案仍然是错误的。tar.gz文件的大小不同,这就是OP所问的。我写了“tarball”,但是指的是“tar gz文件”。Tom并没有真正给出答案,只是提供了一些关于未压缩tarball的信息,这不是OP所问的。这可能是downvotes的原因。你不能仅仅用“你不需要”这样的回答来回答一个“我该怎么做?”的问题,除非他或她在问题中说明了需要什么。 - Nate T
@papo 看起来 Tom S 知道这个答案可能会导致红色信用分。CYA 替代账户?对于问题来说,单一活动的帐户很常见,但对于答案呢? - Nate T
这可能与问题无关,但我得到了我正在寻找的一些信息。谢谢。 - Aditya Kane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接