使用Python编写一个脚本来解压(.tar.gz)文件。

107

我正在尝试编写一个脚本,用于从一个目录中的文件夹中解压缩所有的.tar.gz文件。例如,我将有一个名为( testing.tar.gz)的文件。然后如果我手动操作,我可以按“在此处提取”按钮,然后.tar.gz文件将创建一个新文件,并且命名为testing.tar。最后,如果我重复按“在此处提取”按钮,.tar文件会生成所有的.pdf文件。

我想知道如何实现它,我已经在这里放置了我的代码,但似乎并没有真正起作用。

import os
import tarfile
import zipfile

def extract_file(path, to_directory='.'):
    if path.endswith('.zip'):
        opener, mode = zipfile.ZipFile, 'r'
    elif path.endswith('.tar.gz') or path.endswith('.tgz'):
        opener, mode = tarfile.open, 'r:gz'
    elif path.endswith('.tar.bz2') or path.endswith('.tbz'):
        opener, mode = tarfile.open, 'r:bz2'
    else: 
        raise ValueError, "Could not extract `%s` as no appropriate extractor is found" % path

    cwd = os.getcwd()
    os.chdir(to_directory)

    try:
        file = opener(path, mode)
        try: file.extractall()
        finally: file.close()
    finally:
        os.chdir(cwd)

2
除非使用Python有所必要,否则这听起来更适合用shell脚本完成。 - mfaerevaag
1
extractall 将目标目录作为参数,无需来回切换目录。 - Daniel Persson
如果您将chdir路径更改为压缩文件,则可能会过时。 - Nikolai Ehrhardt
7个回答

167

为什么你要按两次“压缩”才能提取 .tar.gz 文件,当你可以轻松一步完成? 这是一个简单的代码,可以一次提取 .tar 和 .tar.gz 文件:

为什么要多此一举地按两下才能解压缩 .tar.gz 文件呢?只需要一步就能搞定啦!这里有一个简单的代码可以同时解压缩 .tar 和 .tar.gz 文件:

import tarfile

if fname.endswith("tar.gz"):
    tar = tarfile.open(fname, "r:gz")
    tar.extractall()
    tar.close()
elif fname.endswith("tar"):
    tar = tarfile.open(fname, "r:")
    tar.extractall()
    tar.close()

1
这是因为,看起来我拥有的文件是(.tar.gz)格式。但是解压过程中,必须从(.tar.gz)提取到(.gz),然后再次提取才能得到我需要的信息,例如.pdf文件等。 - Alex
9
@Alex fname 是一个字符串,表示你的文件名。 - David Starkey
1
@Alex fname 是你正在尝试解压缩的文件名字符串。 files = [f for f in os.listdir('.') if os.path.isfile(f)] for fname in files: # 做一些事情,例如上面的 "if-elif" 代码。 - Lye Heng Foo
6
你可以在extractall()命令中使用路径参数,例如tar.extractall(path="/new/dir/location")。你也可以获得更多的控制权,例如如果你需要使用extract()仅提取压缩文件中的几个文件。如需更多控制,请参阅man页面。https://docs.python.org/3/library/tarfile.html - Lye Heng Foo
提取(extract())命令的具体链接:https://docs.python.org/3/library/tarfile.html#tarfile.TarFile.extract - Lye Heng Foo
显示剩余5条评论

61
如果您正在使用Python 3,则应该使用shutil.unpack_archive,它适用于大多数常见的存档格式。
shutil.unpack_archive(filename [,extract_dir [,format]]) 解压缩存档。filename是存档的完整路径。 extract_dir是存档解压缩的目标目录名称。如果未提供,则使用当前工作目录。
例如:
def extract_all(archives, extract_path):
    for filename in archives:
        shutil.unpack_archive(filename, extract_path)

4
有没有办法控制提取文件的名称? - Suraj
3
当用户没有根权限时,tarfile 无法运行,但 shutil 可以。 - Lei Yang
1
找到一行Python代码,以最小的麻烦实现我所需的功能,这让我感到非常愉悦 - 谢谢!我预测Python将是最后一种编程语言。 - Mike Honey
@suraj-subramanian,提取路径将包含新名称。例如,如果文件名为“hello.tar.gz”,提取路径可能是“/tmp/my_name_here”。 - Justin Furuness

7
使用上下文管理器:

使用上下文管理器:

import tarfile
<another code>
with tarfile.open(os.path.join(os.environ['BACKUP_DIR'],
                  f'Backup_{self.batch_id}.tar.gz'), "r:gz") as so:
    so.extractall(path=os.environ['BACKUP_DIR'])

4

如果您正在使用Python在jupyter-notebook中,并且在Linux机器上,下面的内容将会有所帮助:

!tar -xvzf /path/to/file.tar.gz -C /path/to/save_directory

! 可以在终端中运行命令。


1

以下方法适用于我下载的.tar.gz文件。它会将文件提取到您指定的目标位置:

import tarfile

from os import mkdir
from os.path import isdir

src_path = 'path/to/my/source_file.tar.gz'
dst_path = 'path/to/my/destination'

# create destination dir if it does not exist
if isdir(dst_path) == False:
    mkdir(dst_path)

if src_path.endswith('tar.gz'):
    tar = tarfile.open(src_path, 'r:gz')
    tar.extractall(dst_path)
    tar.close()

0

您可以使用envoy从Python执行shell脚本:

import envoy # pip install envoy

if (file.endswith("tar.gz")):
    envoy.run("tar xzf %s -C %s" % (file, to_directory))

elif (file.endswith("tar")):
    envoy.run("tar xf %s -C %s" % (file, to_directory))

-3
当我运行你的程序时,对于tar.gz和.tgz文件,它完美地工作了,但是当我打开zip文件时,它没有给我正确的项目,但是.tbz是唯一引发错误的文件。我认为你使用了错误的方法来解压.tbz,因为错误显示我有一个不正确的文件类型,但实际上并不是这样。解决.zip问题的一种方法是使用os.command()并使用命令行(根据您的操作系统)进行解压缩,因为它返回了一个_MACOSX文件夹,里面什么也没有,即使我输入了正确的路径。我遇到的唯一其他错误是你使用了不正确的语法来引发错误。
这是你应该使用的:
raise ValueError("Error message here")

你使用了逗号而没有括号。希望这可以帮到你!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接