bzip2:检查文件的解压缩大小而不实际解压缩它

bzip2:检查文件的解压缩大小而不实际解压缩它

我有一个很大的bzip2压缩文件,我需要检查它的解压缩大小,而不实际解压缩它(类似于gzip -l file.gzxz -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

相关内容