【问题标题】:I want to create a script for unzip (.tar.gz) file via (Python)我想通过(Python)为解压缩(.tar.gz)文件创建一个脚本
【发布时间】:2015-09-02 11:25:01
【问题描述】:

我正在尝试制作一个脚本,用于从一个目录中的文件夹中解压缩所有 .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)

【问题讨论】:

  • 除非有使用 Python 的意义,否则这听起来像是最适合 shell 脚本的工作。
  • extractall 以目标目录为参数,无需来回chdir

标签: python tar unzip gzip


【解决方案1】:

为什么要“按”两次来提取 .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()

【讨论】:

  • 这是因为,看起来我拥有的文件是(.tar.gz)。但是解压过程中,必须先从(.tar.gz)解压到(.gz),再解压一次会给出我需要的信息,比如.pdf文件等
  • 并且您的代码不起作用:如果 (fname.endswith("tar.gz")): NameError: name 'fname' is not defined
  • @Alex fname 将是一个字符串,即您的文件名。
  • @Alex fname 是您尝试解压缩的文件名字符串。 files = [f for f in os.listdir('.') if os.path.isfile(f)] for fname in files: # do something, e.g. the above "if-elif" code.
  • @Matthew 您可以在 extractall() 命令中使用路径参数,例如tar.extractall(path="/new/dir/location")。您也可以拥有更多控制权,例如如果您只需要使用 extract() 提取 tar 文件中的几个文件。如需更多控制,请查看手册页。 docs.python.org/3/library/tarfile.html
【解决方案2】:

如果您使用的是 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)

【讨论】:

  • 有没有办法控制解压文件的名字。
  • 当用户没有root权限时,tarfile不能运行,但shutil可以。
  • 找到一行 python 代码,用最少的麻烦完成我需要的工作,这会激发快乐 - 谢谢!我预测 python 将是最后一种编程语言。
  • @suraj-subramanian,提取路径将包含新名称。例如,如果文件名是“hello.tar.gz”,则 extract_path 可能是“/tmp/my_name_here”
【解决方案3】:

使用上下文管理器:

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】:

    如果您在jupyter-notebooklinux 机器中使用python,则可以执行以下操作:

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

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

    【讨论】:

      【解决方案5】:

      您可以使用 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))
      

      【讨论】:

        【解决方案6】:

        当我运行您的程序时,它对 tar.gz 和 .tgz 文件非常有效,当我打开 zip 时它没有给我正确的项目,但 .tbz 是唯一引发错误的文件。我认为您使用了错误的方法来解压 .tbz,因为错误说我的文件类型不正确,但我没有。解决 .zip 问题的一种方法是向我们发送 os.command() 并使用命令行解压缩(取决于您的操作系统),因为它返回了一个 _MACOSX 文件夹,其中没有任何内容,即使我正确输入了路径。我遇到的唯一其他错误是您使用了不正确的语法来引发错误。
        这是你应该使用的:

        raise ValueError("Error message here")
        

        您使用了逗号且没有括号。希望这会有所帮助!

        【讨论】:

          猜你喜欢
          • 2013-04-27
          • 2011-11-01
          • 2011-10-30
          • 2018-06-26
          • 2013-04-29
          • 2011-02-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多