0

我想写一个script操作许多 zip 文件的程序。所有存档文件中都有相同的文件夹结构。我想改变它。

我正在阅读zip手册一段时间,但我不知道如何执行以下操作。我想知道,这些任务是否可以在不解压缩存档文件的情况下完成?

  1. 将 zip 存档中的文件从文件夹 1 移动到另一个文件夹 2。
  2. 重命名 zip 存档文件中的文件夹。

例子:

zip文件中的原始结构:

       +folder0
         + folder1
            +folder2
               - file1.xyz
               - file3.xyz
               ...
            +folder3
               - file4.xyz
               ...
          ...

我想将其更改为:

        +newFolderName
            +folder2
               - file1.xyz
               - file3.xyz
               ...
            +folder3
               - file4.xyz
               ...

一种可能的方式:

  1. 将子文件夹移动folder1folder0
  2. 删除folder1
  3. 重命名folder0newFolderName

为什么我需要在不解压缩存档文件的情况下执行此操作:

  • 磁盘空间不足(压缩文件很大)
  • 正如我在桌面模式下所经历的那样,在 zip 文件中重命名文件夹比解压缩->更改文件夹名称->再次压缩要快得多。我需要一个尽可能快地运行的脚本。
  • 这个想法失败了,创建一个 ram 磁盘并在那里进行解压缩(内存不足)
  • 另一个想法:我可以将 zip 文件挂载为分区,然后像real分区一样操作吗?

zip如果应用程序不是此任务的最佳工具,我可以在服务器上安装应用程序。

有人有同样任务的经验吗?

谢谢你的建议。

编辑:

正如我在@Nickolay Olshevsky 的回答中读到的那样,此功能可能无法zip在其他官方 linux 命令行工具/应用程序中实现。所以我开始以不同的方式寻找解决方案。

PHP 可以用作 CGI 脚本,我在服务器上有 PHP 解释器,所以解决方案(在 PHP 中作为 CGI 脚本)是:(这样的东西可以用 libzip 编写 python/ruby/... 脚本或 c/c++ 应用程序,以及许多其他编程/脚本语言)

#!/usr/bin/php5
<?php
      //requires PHP5.3+ 
      $path = $argc?$argv[1]:'./';   
      $dh = opendir($path);               
      $oldPath = 'folder0/folder1/';
      $newPath = 'newFolder/'
      $zip = new ZipArchive();
      $warning = false;
      while( $entry = readdir( $dh ) ){
          if( 'zip' == array_pop(explode('.',$entry)) && $zip->open($entry) ){
               $success = true;
               print "Processing zip archive $path$entry: \n";
               for( $i=0; $i < $zip->numFiles; $i++ ){  
                    $oldName = $zip->getNameIndex($i);                          
                    $newName = preg_replace("#^$oldPath#",
                                          $newpath,
                                          $oldName);
                    print "  Renaming $oldName to $newName ... "
                    if($zip->renameIndex($i,$newName)){
                        print "OK\n";
                    }else{
                        $warning = true;
                        $success = false;
                        print "FAILED\n";
                        break;
                    }
              }
              if( $zip->close() ){
                  print "$path$entry PROCESSED\n";
              }else{
                  print "Warning: Something went wrong with $path$entry !!!\n";
              }
          }
      }
      closedir($dh);
      return $warning?1:0;
?>

但回到我原来的问题:

当有人找到仅使用 bash 和官方(debian)linux 命令行 zip/gzip/... 等工具的解决方案时,我接受该答案。

4

1 回答 1

1

由于 ZIP 存档结构,这不是一件容易的事。那里的路径存储为可变长度字段,当您更改文件的路径时,它将占用更多/更少的字节,您需要在此文件记录之后移动所有数据。这是可能的,无需重新压缩,但我怀疑有人实现了这样的功能。

于 2013-04-29T14:10:59.213 回答