【问题标题】:Is it possible to extract single file from tar bundle in python是否可以从python中的tar包中提取单个文件
【发布时间】:2013-12-06 22:44:20
【问题描述】:

我需要从一个巨大的 svn 存储库中获取几个文件。获取整个 repo 需要将近一个小时。我要查找的文件是 tar 包的一部分。

是否可以只从 tar 包中获取这两个文件而不通过 Python 代码提取整个包?

如果是这样,谁能告诉我该怎么做?

【问题讨论】:

  • 您不需要 Python 从 tarball 中提取单个文件。 man tar 找到您需要的选项。当然,您需要先使用 tarball,然后才能对其进行操作...
  • MattDMo 我需要以编程方式完成,我的 tarball 放在 svn repo 中。

标签: python git svn


【解决方案1】:

听起来你的问题有两个部分:

  1. 从 SVN 存储库中获取单个 tar 包,而不包含存储库的其余文件。
  2. 使用 Python 从检索到的包中提取两个文件。

对于第一部分,我将简单地参考this post 上的svn export 和稀疏结帐。

对于第二部分,这是从检索到的 tarball 中提取两个文件的解决方案:

import tarfile

files_i_want = ['path/to/file1','path/to/file2']

tar = tarfile.open("bundle.tar")
tar.extractall(members=[x for x in tar.getmembers() if x.name in files_i_want])

【讨论】:

    【解决方案2】:

    这是从 svn 获取 tar 文件并从中提取一个文件的一种方法:

    import tarfile
    from subprocess import check_output
    # Capture the tar file from subversion
    tmp='/home/me/tempfile.tar'
    open(tmp, 'wb').write(check_output(["svn", "cat", "svn://url/some.tar"]))
    # Extract the file we want, saving to current directory
    tarfile.open(tmp).extract('dir1/fname.ext', path='dir2')
    

    其中 'dir1/fname.ext' 是 tar 存档中所需文件的完整路径。它将保存在 'dir2/dir1/fname.ext' 中。如果省略路径参数,它将保存在当前目录下的 'dir1/fname.ext' 中。

    上面可以这样理解。在普通的 shell 命令行上,svn cat url 告诉 subversion 将 url 定义的文件发送到标准输出(有关更多信息,请参阅svn help cat)。 url 可以是 svn 可以理解的任何类型的 url,例如 svn://...svn+ssh://...file://...。我们使用 subprocess 模块在 python 控制下运行此命令。为此,svn cat url 命令被分解为一个列表:["svn", "cat", "url"]。此svn 命令的输出保存到由tmp 变量定义的本地文件中。然后我们使用 tarfile 模块来提取你想要的文件。

    或者,您可以使用 extractfile 方法将文件数据捕获到 python 变量:

    handle = t.extractfile('dir1/fname.ext')
    print handle.readlines() # show file contents
    

    根据文档,tarfile 应该接受子进程的标准输出作为文件句柄。这将简化代码并消除在本地保存 tar 文件的需要。但是,由于一个错误,Issue 10436,这将不起作用。

    【讨论】:

    • 感谢 John1024 获取 tar 文件,我的调用将是这样的,t.extract('dir/fname.ext'),对吗?也可以远程读取/提取 tar 文件。我的意思是来自 svn repo?
    • 是的 extract 语法。你可以使用python模块pysvn通过svn获取tar文件。例如,请参阅 [pysvn.tigris.org/docs/pysvn_prog_guide.html].
    • @RajanPathak 我刚刚用一种从通过 svn 提取 tar 文件开始的方法更新了答案。
    • 感谢 John 的友好回复,有一点我想知道 Popen 调用,它是如何工作的。它的参数 "svn","cat" 在这里是什么意思,我需要提供 svn+在这里单独使用 ssh 或 svn 就足够了。
    • 另外,它会将 tarball 下载到我的本地计算机然后解压缩文件,还是仅远程读取 tarball 并将所需文件放置到我的计算机上?
    【解决方案3】:

    也许你想要这样的东西?

    #!/usr/local/cpython-3.3/bin/python
    
    import tarfile as tarfile_mod
    
    def main():
        tarfile = tarfile_mod.TarFile('tar-archive.tar', 'r')
        if False:
            file_ = tarfile.extractfile('etc/protocols')
            print(file_.read())
        else:
            tarfile.extract('etc/protocols')
        tarfile.close()
    
    main()
    

    【讨论】:

    • 感谢 dstromberg 的回答,协议文件将被提取到当前工作目录,对吗?压缩包可以在 svn 远程仓库本身读取吗?
    • if 可以提取到内存,也可以提取到磁盘;您的偏好。如果你想从 SVN 读取文件,并且你在 Linux 上,你可以试试 svnfs: jmadden.eu/index.php/svnfs 。如果你不在 Linux 上,或者你想避免使用新的文件系统,你可以在使用上面的代码之前“svn export host.name.com/dir/file.tar”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多