我想编写一个操作许多zip文件的script
。所有存档文件中都有相同的文件夹结构。我想改变它。
我正在阅读zip
手册一段时间,我无法弄清楚如何执行以下操作。
我想知道,这些任务是否可以在不解压缩存档文件的情况下完成?
示例:
zip文件中的原始结构:
+folder0
+ folder1
+folder2
- file1.xyz
- file3.xyz
...
+folder3
- file4.xyz
...
...
我想将其更改为:
+newFolderName
+folder2
- file1.xyz
- file3.xyz
...
+folder3
- file4.xyz
...
一种可能的方式:
folder1
的子文件夹移至folder0
folder1
folder0
重命名为newFolderName
为什么我需要在不解压缩存档文件的情况下执行此操作:
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 / ...等工具的解决方案时,我会接受这个答案。
答案 0 :(得分:1)
由于ZIP存档结构,这不是一件容易的事。那里的路径存储为可变长度字段,当您更改文件的路径时,它将需要更多/更少的字节,您需要在此文件记录之后移动所有数据。这是可能的,没有重新压缩,但我怀疑有人实现了这样的功能。