【问题标题】:Method to get file byte offsets (and lengths) in tar files在 tar 文件中获取文件字节偏移量(和长度)的方法
【发布时间】:2017-08-20 11:36:31
【问题描述】:

我有一个包含数百万个文件的大型 tar 文件。出于效率原因,我不想将文件解压缩到磁盘。

相反,给定一个所需的文件名,我想编写一个脚本,例如Python 从 tar 文件中提取相关数据块。

有没有一种简单的方法来创建一个索引,告诉我 tar 文件中每个文件的起始字节和长度,例如我可以转储到磁盘作为索引以用于上述 Python 脚本吗?

也许 tar 命令可以做到这一点,但我在手册页中没有看到任何明显的内容。

tar 未压缩。

提前致谢。

【问题讨论】:

  • 为什么不使用有索引的zip/7z/xz/etc?

标签: python linux file tar


【解决方案1】:

Python 代码的性能不是很好。我使用下面的 awk 脚本来处理一个大的 tar 文件。

tar -tvf <tar-file> -R | awk '
BEGIN{
  getline;
  f=$8;
  s=$5;
}
{
  offset = int($2) * 512 - and((s+511), -512)
  print offset,s,f;
  f=$8;
  s=$5;
}'

【讨论】:

  • awk 这是干什么用的? gawk 5.0.0 错误:and: argument 1 negative value -512 is not allowed
  • 啊,在 4.2 中删除了对负操作数的支持:gnu.org/software/gawk/manual/html_node/…
  • 显然从位 and 这已经假设正在使用的数字表示是二进制补码,所以我只是将 -512 替换为 compl(512)+1 以获得在 gawk 5 中工作的东西而没有更糟的假设:D
【解决方案2】:

为了其他有类似用例的人的利益(即想要建立一个能够对 tar 文件进行随机访问的索引),最后我在http://fomori.org/blog/?p=391 改编了一个方便的实用程序,其本质是(在 Python 中):

fp=open('index.txt','wt')
ctr=0
with tarfile.open(tarfname, 'r|') as db:
  for tarinfo in db:
     currentseek = tarinfo.offset_data
     rec = "%d\t%d\t%d\t%s\n" % (ctr,tarinfo.offset_data, tarinfo.size, tarinfo.name)
       fp.write(rec)
       ctr += 1
     if ctr % 1000 == 0:
        db.members = []
fp.close()

在 %1000 的检查可以节省 RAM。我敢肯定这会更整洁。

【讨论】:

    【解决方案3】:
    tar -O -xf <tar-file> <file-you-want-to-extract> | <your-python-program>
    

    【讨论】:

    • 谢谢,但这会将文件解压缩到磁盘。见 OP - 我不想这样做。我想在 tar 中建立所有起始字节和文件长度的索引......然后我将编写一个脚本来寻找相关位置并提取数据。
    • 我修改了 linux 命令来避免使用 disk 。恕我直言,避免重写 tar。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 1970-01-01
    • 2012-11-30
    • 2016-12-27
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    相关资源
    最近更新 更多