简体   繁体   English

在不解压缩的情况下以zip文件(linux &&(bash || cgi脚本))操作文件夹结构

[英]Manipulate folder struct in a zip file ( linux && (bash || cgi script) ) without uncompressing

I want to write a script that manipulates many zip files. 我想编写一个处理许多zip文件的script Same folder struct are in all archive files. 所有存档文件中都包含相同的文件夹结构。 I would like to change that. 我想改变这一点。

I am reading for a while the zip manual and i can not figure out how to do the following. 我正在阅读一段时间的zip手册,但我不知道如何执行以下操作。 I am wondering, are these tasks possible without unzipping the archive file? 我想知道,在不解压缩存档文件的情况下是否可以执行这些任务?

  1. Move files inside a zip archive from a folder1 to an other folder2. 将zip存档中的文件从文件夹1移动到另一个文件夹2。
  2. Rename folders in a zip archive file. 重命名zip存档文件中的文件夹。

Example: 例:

The original struct in the zip file: 压缩文件中的原始结构:

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

I want to change this to: 我想将其更改为:

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

A possible way : 可能的方法:

  1. Move the subfolders of folder1 to folder0 移动的子folder1folder0
  2. delete folder1 删除文件folder1
  3. rename folder0 to newFolderName 重命名folder0newFolderName

Why do i need to do this without uncompress the archive file: 为什么需要在不解压存档文件的情况下执行此操作:

  • Not enough space on disk ( the compressed files are big ) 磁盘上没有足够的空间(压缩文件很大)
  • As i experienced in desktop mode, the renaming of a folder in zip file is mutch faster than uncompress->change the folder name->compress again. 如我在桌面模式下所经历的,重命名zip文件中的文件夹比解压缩->更改文件夹名称->再次压缩要快得多。 I need a script that runs as fast as it possible. 我需要一个尽可能快地运行的脚本。
  • The idea is failed, to create a ram disk and do the uncompressing there (not enough memory) 这个想法失败了,无法创建ram磁盘并在那里进行解压缩(内存不足)
  • An other idea: can i mount the zip file as a partition, and then manipulate like a real partition ? 另一个想法:我可以将zip文件挂载为一个分区,然后像real分区一样进行操作吗?

I can install applications on the server, if zip application is not the best tool for this task. 如果zip应用程序不是执行此任务的最佳工具,则可以在服务器上安装应用程序。

Anyone have experiences with same task? 任何人都有完成相同任务的经验吗?

Thanks for advice. 谢谢你的建议。

EDIT: 编辑:

As I read in @Nickolay Olshevsky 's answer this feature might not be implemented in zip and in other official linux command line tools/applications. 正如我在@Nickolay Olshevsky的答案中所读到的,此功能可能无法在zip和其他官方linux命令行工具/应用程序中实现。 So I began to find a solution on a bit different way. 因此,我开始以不同的方式找到解决方案。

PHP can be used as CGI script, and I have PHP interpreter on the server so the solution (in PHP as CGI script) is: (Something like this can be written python/ruby/... script or c/c++ app with libzip, and many other programming/scripting languages ) PHP可以用作CGI脚本,并且我在服务器上具有PHP解释器,因此解决方案(在PHP中为CGI脚本)是:(类似这样的东西可以用python / ruby​​ / ...脚本或带有libzip的c / c ++ app编写。 ,以及许多其他编程/脚本语言)

#!/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;
?>

But back to my original question : 但是回到我原来的问题:

When somebody find a solution what uses only bash and official (debian) linux command line zip/gzip/... etc tools i accept that answer. 当有人找到解决方案时,仅使用bash和官方(debian)linux命令行zip / gzip / ...等工具,我接受该答案。

This is not an easy task due to ZIP archive structure. 由于ZIP存档结构,这并非易事。 Paths there stored as variable-length fields, and when you will change the path of file, it will take more/less bytes and you'll need to move all the data after this file record. 那里的路径存储为可变长度字段,当您更改文件的路径时,它将占用更多/更少的字节,并且需要在此文件记录之后移动所有数据。 This is possible without recompression, but I doubt that somebody implemented such feature. 无需重新压缩就可以实现,但是我怀疑有人实现了这种功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM