如何部分提取压缩的巨大纯文本文件?

k0p*_*kus 20 zip text-processing

我有一个大小为 1.5 GB 的 zip 文件。

它的内容是一个可笑的大型纯文本文件 (60 GB),目前我的磁盘上没有足够的空间来提取它,我也不想提取它,即使我有。

至于我的用例,如果我可以检查部分内容就足够了。

因此,我想将文件解压缩为流并访问文件的范围(就像可以通过普通文本文件的头部和尾部)。

通过内存(例如从 32GB 标记开始提取最大 100kb)或按行(给我纯文本行 3700-3900)。

有没有办法实现这一目标?

Sté*_*las 31

注意gzip可以解压zip文件(至少是文件中的第一个条目zip)。因此,如果该存档中只有一个大文件,您可以执行以下操作:

gunzip < file.zip | tail -n +3000 | head -n 20
Run Code Online (Sandbox Code Playgroud)

例如,从第 3000 行开始提取 20 行。

或者:

gunzip < file.zip | tail -c +3000 | head -c 20
Run Code Online (Sandbox Code Playgroud)

对于与字节相同的事情(假设head支持的实现-c)。

对于存档中的任意成员,以 Unixy 方式:

bsdtar xOf file.zip file-to-extract | tail... | head...
Run Code Online (Sandbox Code Playgroud)

使用head内置的ksh93(例如 when/opt/ast/bin在前面$PATH),您还可以执行以下操作:

.... | head     -s 2999      -c 20
.... | head --skip=2999 --bytes=20
Run Code Online (Sandbox Code Playgroud)

请注意,在任何情况下gzip/ bsdtar/unzip总是需要解压缩(和丢弃在这里),导致了部分要提取的文件的整个部分。这取决于压缩算法的工作方式。


ton*_*ioc 14

使用 unzip -p 和 dd 的一种解决方案,例如以 1000 个块偏移量提取 10kb:

$ unzip -p my.zip | dd ibs=1024 count=10 skip=1000 > /tmp/out
Run Code Online (Sandbox Code Playgroud)

注意:我没有用非常大的数据尝试这个......

  • 通常,在带有计数或跳过的管道上使用 `dd` 是不可靠的,因为它会执行 ** 最多 ** 1024 个字节的许多 `read()`。因此,只有当 `unzip` 以大小为 1024 的倍数的块写入管道时,它才能保证正常工作。 (5认同)