在没有解压缩的情况下在zip文件(linux&&(bash || cgi脚本))中处理文件夹结构

时间:2013-04-29 13:50:47

标签: linux bash shell zip cgi

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

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

  1. 将zip存档中的文件从folder1移动到其他文件夹2。
  2. 重命名zip存档文件中的文件夹。
  3. 示例:

    zip文件中的原始结构:

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

    我想将其更改为:

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

    一种可能的方式:

    1. folder1的子文件夹移至folder0
    2. 删除folder1
    3. folder0重命名为newFolderName
    4. 为什么我需要在不解压缩存档文件的情况下执行此操作:

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

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

      任何人都有相同任务的经历吗?

      感谢您的建议。

      编辑:

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

      PHP可以用作CGI脚本,我在服务器上有PHP解释器,因此解决方案(在PHP中作为CGI脚本)是: (像这样的东西可以写成python / ruby​​ / ...脚本或带有libzip的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 / ...等工具的解决方案时,我会接受这个答案。

1 个答案:

答案 0 :(得分:1)

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