我有一个很大的bzip2
压缩文件,我需要检查它的解压缩大小,而不实际解压缩它(类似于gzip -l file.gz
或xz -l file.xz
)。如何使用 来完成此操作bzip2
?
答案1
就像评论和链接答案中提到的那样,唯一可靠的方法是解压缩(在管道中)并进行字节计数。
$ bzcat file.bz2 | wc -c
1234
或者找到一些无需多余管道即可完成此操作的工具(可能会稍微更有效):
$ 7z t file.bz2
[...]
Everything is Ok
Size: 1234
这也适用于 gzip 和其他格式。尽管gzip -l file.gz
打印了尺寸,但它可能是错误的结果。一旦文件超过一定大小,您会得到如下内容:
$ gzip --list foobar.gz
compressed uncompressed ratio uncompressed_name
97894400 58835168 -66.4% foobar
$ gzip --list foobar.gz
compressed uncompressed ratio uncompressed_name
4796137936 0 0.0% foobar
或者,如果文件是串联的或根本没有正确创建:
$ truncate -s 1234 foobar
$ gzip foobar
$ cat foobar.gz foobar.gz > barfoo.gz
$ gzip -l barfoo.gz
compressed uncompressed ratio uncompressed_name
74 1234 96.0% barfoo
$ zcat barfoo.gz | wc -c
2468
尺寸不匹配,所以这无论如何都不可靠。
有时你可以作弊,具体取决于档案中的内容。例如,如果它是压缩的文件系统映像,并且开头有元数据标头,则可以仅解压缩该标头,然后从中读取文件系统的总大小。
$ truncate -s 1234M foobar.img
$ mkfs.ext2 foobar.img
$ bzip2 foobar.img
$ bzcat foobar.img.bz2 | head -c 1M > header.img
$ tune2fs -l header.img
tune2fs 1.45.4 (23-Sep-2019)
Filesystem volume name: <none>
Last mounted on: <not available>
Filesystem UUID: 95b64880-c4a7-4bea-9b63-6fdcc86d0914
[...]
Block count: 315904
Block size: 4096
因此,通过提取一小部分,您可以了解到这是 315904 个 4096 字节的块,结果为 1234 MiB。
无法保证压缩文件的实际大小(可能更大或更小),但假设没有奇怪的东西,它比gzip -l
任何情况都更值得信赖。
最后但并非最不重要的一点是,如果这些文件是您首先创建的,只需记录大小即可。
答案2
这个问题已经有答案了这里。粘贴如下:
正如其他人所指出的,bzip2 没有提供太多信息。但这种技术是有效的——您必须解压缩文件,但不必将解压缩的数据写入磁盘,这对您来说可能是一个“足够好”的解决方案:
$ ls -l foo.bz2
-rw-r--r-- 1 ~quack ~quack 2364418 Jul 4 11:15 foo.bz2
$ bzcat foo.bz2 | wc -c # bzcat decompresses to stdout, wc -c counts bytes
2928640 # number of bytes of decompressed data
您可以将该输出传输到其他内容中,以提供人类可读的形式:
$ ls -lh foo.bz2
-rw-r--r-- 1 quack quack 2.3M Jul 4 11:15 foo.bz2
$ bzcat foo.bz2 | wc -c | perl -lne 'printf("%.2fM\n", $_/1024/1024)'
2.79M