【问题标题】:How to copy and extract .gz files using python如何使用python复制和提取.gz文件
【发布时间】:2014-12-22 01:17:51
【问题描述】:

我刚开始学习python,有一个问题。

如何创建一个脚本来执行以下操作:(将在 bash 中写下我是如何做到的)

  1. <file>.gz从远程服务器1复制到本地存储。

    cp /dumps/server1/file1.gz /local/

  2. 然后在本地提取该文件。

    gunzip /local/file1.gz

  3. 然后将提取文件复制到远程服务器2(用于归档和重复数据删除)

    cp /local/file1.dump /dedupmount

  4. 删除 .gz 文件的本地副本以释放“临时”存储空间

    rm -rf /local/file1.gz

我需要为所有文件循环运行所有这些。 所有文件和目录都是 NFS 挂载在同一台服务器上。

for 循环遍历 /dump/ 文件夹并查找 .gz 文件。 每个.gz 文件将首先复制到/local 目录,然后在那里解压缩。 解压后,解压后的.dmp文件将被复制到/dedupmount文件夹进行归档。

我的头在墙上怎么写。

【问题讨论】:

    标签: python linux backup directory gunzip


    【解决方案1】:

    你可以使用模块 urlopen

    import urllib
    #urlretrieve will save the file to local drive
    urllib.urlretrieve(url,file_name_to_save)
    

    现在你可以使用gunzip utitlty来解压,使用os.system

    【讨论】:

      【解决方案2】:

      Python 解决方案

      虽然 shell 代码可能更短,但整个过程可以在 python 中本地完成。 python解决方案的重点是:

      • 使用gzip 模块,gzip 压缩文件与普通文件一样易于阅读。

      • 要获取源文件列表,使用glob 模块。它是根据 shell glob 功能建模的。

      • 要操作路径,请使用 python os.path 模块。它为文件系统提供了一个独立于操作系统的接口。

      这里是示例代码:

      import gzip
      import glob
      import os.path
      source_dir = "/dumps/server1"
      dest_dir = "/dedupmount"
      
      for src_name in glob.glob(os.path.join(source_dir, '*.gz')):
          base = os.path.basename(src_name)
          dest_name = os.path.join(dest_dir, base[:-3])
          with gzip.open(src_name, 'rb') as infile:
              with open(dest_name, 'wb') as outfile:
                  for line in infile:
                      outfile.write(line)
      

      此代码从 remote1 服务器读取并写入 remote2 服务器。除非您需要,否则不需要本地副本。

      在这段代码中,所有的解压都是由本地机器上的 CPU 完成的。

      外壳代码

      为了比较,这里是等效的shell代码:

      for src in /dumps/server1/*.gz
      do
          base=${src##*/}
          dest="/dedupmount/${base%.gz}"
          zcat "$src" >"$dest"
      done
      

      三步 Python 代码

      这种稍微复杂一点的方法实现了 OP 的三步算法,该算法使用本地机器上的临时文件:

      import gzip
      import glob
      import os.path
      import shutil
      
      source_dir = "./dumps/server1"
      dest_dir = "./dedupmount"
      tmpfile = "/tmp/delete.me"
      
      for src_name in glob.glob(os.path.join(source_dir, '*.gz')):
          base = os.path.basename(src_name)
          dest_name = os.path.join(dest_dir, base[:-3])
          shutil.copyfile(src_name, tmpfile)
          with gzip.open(tmpfile, 'rb') as infile:
              with open(dest_name, 'wb') as outfile:
                  for line in infile:
                      outfile.write(line)
      

      这会将源文件复制到本地计算机上的临时文件tmpfile,然后将其从那里枪压缩到目标文件。 tmpfile 将被此脚本的每次调用覆盖。

      临时文件可能是一个安全问题。为避免这种情况,请将临时文件放置在只有运行此脚本的用户可写的目录中。

      【讨论】:

      • 非常感谢您提供详尽的解释 :) 问题是,我确实需要“本地”目录进行提取,因为文件非常大(压缩后大约 100GB,解压后超过 1TB) ,所以我希望所有 I/O 都转到本地服务器磁盘,并在提取后将解压缩的 .dmp 文件复制到远程重复数据删除存储上的 dedup 挂载。所以这就是为什么它的 3 步操作。 1. 从源服务器复制到本地磁盘。 2. 本地化。 3. 将提取的文件复制到远程去重存储:)
      • @bflance 实际上,在当前答案中,zcat/gzip 确实在本地运行。因此,提取是在本地完成的。 server1 上运行的唯一代码是 NFS,它只是在做最低限度的读取源文件。同样,在 server2 上运行的唯一代码是 NFS,它将文件写入磁盘。这在很大程度上是可能的,因为 gzip 格式是为在管道中使用而设计的。
      • 是的,但是由于它是通过管道提取的,它会一直从远程服务器“管道”该 .gz 文件,直到它被提取并且它的长时间和大量 I/O(除非我遗漏了什么) .这些文件很大,我们希望尽可能限制远程服务器上的 I/O,以防止性能影响以及“停止”NFS 挂载的机会。这就是为什么我们有“专用”服务器仅用于将 .gz 文件提取到 RAID0 阵列中的快速本地驱动器。通过直接从远程服务器中提取,我猜它会产生过多的负载..
      • @bflance 虽然它不会改变 server1 的总 IO,但三步计划很简单:查看更新的答案。
      猜你喜欢
      • 1970-01-01
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-10
      • 1970-01-01
      • 2021-05-15
      • 1970-01-01
      相关资源
      最近更新 更多