如何修改 gzip 压缩的 tar 文件中的文件?

发布于 2024-10-10 17:22:22 字数 405 浏览 3 评论 0原文

我想编写一个(最好是 python)脚本来修改 gzipped tar 文件中一个文件的内容。该脚本必须在 FreeBSD 6+ 上运行。

基本上,我需要:

  • 打开 tar 文件
  • 如果 tar 文件中有 _MY_FILE_ ,则 :
    • 如果 _MY_FILE_ 中有匹配 /RE/ 的行:
    • 在匹配行后插入 LINE
  • 将内容重写到 tar 文件中,保留除文件大小之外的所有元数据

我将对很多文件重复此操作。

Python 的 tarfile 模块在压缩时似乎无法打开 tar 文件进行读/写访问,这具有一定的意义。但是,我也找不到复制经过修改的 tar 文件的方法。

有没有简单的方法可以做到这一点?

I want to write a (preferably python) script to modify the content of one file in a gzipped tar file. The script must run on FreeBSD 6+.

Basically, I need to:

  • open the tar file
  • if the tar file has _MY_FILE_ in it:
    • if _MY_FILE_ has a line matching /RE/ in it:
    • insert LINE after the matching line
  • rewrite the content into the tar file, preserving all metadata except the file size

I'll be repeating this for a lot of files.

Python's tarfile module doesn't seem to be able to open tar files for read/write access when they're compressed, which makes a certain amount of sense. However, I can't find a way to copy the tar file with modifications, either.

Is there an easy way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

傻比既视感 2024-10-17 17:22:23

我认为 David Phillips 已经回答得很好,但这里有一些示例代码:

with tarfile.open(input_tar_file, 'r:gz') as input_archive:
    with tarfile.open(output_tar_file, 'w:gz') as output_archive:
        for name in input_archive.getnames():
            info = input_archive.getmember(name)
            file = input_archive.extractfile(name)
            print(f'loaded {name} size {info.size}')
            output_archive.addfile(info, file)

此代码将 input_tar_file 复制到 output_tar_file。如果您想修改某些内容,请从 print() 调用开始。在那里,您可以检查输入、丢弃它、根据需要修改它。

需要记住的事情:

  • 在将文件写入该目录之前,请确保先写入该目录。
  • 添加文件时,大小会被指定两次。其中一个位置位于 info.size 中,另一个位置由 file 流的长度隐式给出。

I think David Phillips already answered quite well, but here's some example code on top:

with tarfile.open(input_tar_file, 'r:gz') as input_archive:
    with tarfile.open(output_tar_file, 'w:gz') as output_archive:
        for name in input_archive.getnames():
            info = input_archive.getmember(name)
            file = input_archive.extractfile(name)
            print(f'loaded {name} size {info.size}')
            output_archive.addfile(info, file)

This code does a copy of the input_tar_file to the output_tar_file. If you want to modify things, start at the print() call. There, you can inspect the input, discard it, modify it as you desire.

Things to keep in mind:

  • Make sure you write a directory before writing a file into that directory.
  • The size is kind-of given twice when adding a file. One place is in info.size, the other is implicitly given by the length of the file stream.
七堇年 2024-10-17 17:22:22

不要将 tar 文件视为可以读/写的数据库——事实并非如此。 tar 文件是文件的串联。要修改中间的文件,您需要重写该文件的其余部分。 (对于特定大小的文件,您可能能够利用块填充)

您想要做的是按文件处理 tarball 文件,将文件(经过修改)复制到新的 tarball 中。 Python tarfile 模块应该可以轻松做到这一点。您应该能够通过将属性从旧 TarInfo 对象复制到新对象来保留这些属性。

Don't think of a tar file as a database that you can read/write -- it's not. A tar file is a concatenation of files. To modify a file in the middle, you need to rewrite the rest of the file. (for files of a certain size, you might be able to exploit the block padding)

What you want to do is process the tarball file by file, copying files (with modifications) into a new tarball. The Python tarfile module should make this easy to do. You should be able to retain the attributes by copying them from the old TarInfo object to the new one.

樱花坊 2024-10-17 17:22:22

我没有看到删除单个文件的简单方法。您可以轻松提取一个或全部文件,然后添加所需的任何文件。

我认为唯一的方法是:

  • 使用 python tarfile 打开 tarfile,重命名它。
  • 为原始文件名创建一个重复的空 tar
  • 重新添加所有文件,在重新添加之前更改您需要的文件
  • 在重新创建时读取文件时,请务必重置正确的格式

    tarfile.USTAR_FORMAT
    POSIX.1-1988 (ustar) 格式。
    tarfile.GNU_FORMAT
    GNU tar 格式。
    tarfile.PAX_FORMAT
    POSIX.1-2001 (pax) 格式。
    tarfile.DEFAULT_FORMAT

http://docs.python.org/library/tarfile.html

I don't see an easy way to remove a single file. You can easily extract one or all, then add any files needed.

I think that the only way is:

  • Open the tarfile using python tarfile, rename it.
  • Create a duplicate empty tar for the original file name
  • Re-add all the files, changing the one you need before re-add
  • Be sure to reset the correct format when you read it on re-creation

    tarfile.USTAR_FORMAT
    POSIX.1-1988 (ustar) format.
    tarfile.GNU_FORMAT
    GNU tar format.
    tarfile.PAX_FORMAT
    POSIX.1-2001 (pax) format.
    tarfile.DEFAULT_FORMAT

http://docs.python.org/library/tarfile.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文