Regex perl压缩没有工作目录文件路径的文件夹
我正在尝试将包含文件和子文件夹(包含文件)的文件夹压缩到一个zip文件中。我仅限于核心perl模块,因此我尝试使用IO::Compress::Zip。我想删除工作目录文件路径,但在我的压缩文件夹之前似乎有一个空白的第一个文件夹,就像有一个尾随的“/”我还没有摆脱Regex perl压缩没有工作目录文件路径的文件夹,regex,perl,zip,compression,Regex,Perl,Zip,Compression,我正在尝试将包含文件和子文件夹(包含文件)的文件夹压缩到一个zip文件中。我仅限于核心perl模块,因此我尝试使用IO::Compress::Zip。我想删除工作目录文件路径,但在我的压缩文件夹之前似乎有一个空白的第一个文件夹,就像有一个尾随的“/”我还没有摆脱 use Cwd; use warnings; use strict; use File::Find; use IO::Compress::Zip qw(:all); my $cwd = getcwd(); $cwd =~ s/[
use Cwd;
use warnings;
use strict;
use File::Find;
use IO::Compress::Zip qw(:all);
my $cwd = getcwd();
$cwd =~ s/[\\]/\//g;
print $cwd, "\n";
my $zipdir = $cwd . "\\source_folder";
my $zip = "source_folder.zip";
my @files = ();
sub process_file {
next if (($_ eq '.') || ($_ eq '..'));
if (-d && $_ eq 'fp'){
$File::Find::prune = 1;
return;
}
push @files, $File::Find::name if -f;
}
find(\&process_file, $cwd . "\\source_folder");
zip \@files => "$zip", FilterName => sub{ s|\Q$cwd|| } or die "zip failed: $ZipError\n";
我还尝试使用“CanonicalName=>1”选项,该选项似乎保留了除驱动器号(C:)之外的文件路径。
替换
s[^$dir/][]
无所事事
s<.*[/\\]><>
s
让我完全没有文件夹结构
我错过了什么
更新
红色级别是意外的,并且不是必需的,win explorer无法看到超出此级别的内容。这对我很有用:
use Cwd;
use warnings;
use strict;
use File::Find;
use IO::Compress::Zip qw(:all);
use Data::Dumper;
my $cwd = getcwd();
$cwd =~ s/[\\]/\//g;
print $cwd, "\n";
my $zipdir = $cwd . "/source_folder";
my $zip = "source_folder.zip";
my @files = ();
sub process_file {
next if (($_ eq '.') || ($_ eq '..'));
if (-d && $_ eq 'fp') {
$File::Find::prune = 1;
return;
}
push @files, $File::Find::name if -f;
}
find(\&process_file, $cwd . "/source_folder");
print Dumper \@files;
zip \@files => "$zip", FilterName => sub{ s|\Q$cwd/|| } or die "zip failed: $ZipError\n";
我在对find()的调用中将路径分隔符更改为“/”,并在FilterName子项中将其剥离。
控制台:
您的脚本有两个问题 首先,在脚本中混合使用Windows和Linux/Unix路径。让我举例说明 我已经创建了一个名为source\u folder的子目录来匹配您的脚本
$ dir source_folder
Volume in drive C has no label.
Volume Serial Number is 7CF0-B66E
Directory of C:\Scratch\source_folder
26/11/2018 19:48 <DIR> .
26/11/2018 19:48 <DIR> ..
26/11/2018 17:27 840 try.pl
01/06/2018 13:02 6,653 url
2 File(s) 7,493 bytes
find(\&process_file, $cwd . "\\source_folder");
windows和Unix路径的混合和匹配是在脚本的这一行中创建的
$ dir source_folder
Volume in drive C has no label.
Volume Serial Number is 7CF0-B66E
Directory of C:\Scratch\source_folder
26/11/2018 19:48 <DIR> .
26/11/2018 19:48 <DIR> ..
26/11/2018 17:27 840 try.pl
01/06/2018 13:02 6,653 url
2 File(s) 7,493 bytes
find(\&process_file, $cwd . "\\source_folder");
您正在将$cwd中的Unix样式路径与windows部件“\source\u文件夹”连接起来
将行更改为使用正斜杠,而不是反斜杠,以获得一致的Unix样式路径
find(\&process_file, $cwd . "/source_folder");
第二个问题是这条线
zip \@files => "$zip",
FilterName => sub{ s|\Q$cwd|| },
BinmodeIn =>1
or die "zip failed: $ZipError\n";
替代项,s |\Q$cwd |
,需要一个额外的“/”,如s |\Q$cwd/|
,以确保添加到zip存档的路径是相对路径。所以这条线变成了
zip \@files => "$zip", FilterName => sub{ s|\Q$cwd/|| } or die "zip failed: $ZipError\n";
完成这两个更改后,我可以在资源管理器中查看zip文件,并在使用命令行解压时获取unix样式的相对路径
$ unzip -l source_folder.zip
Archive: source_folder.zip
Length Date Time Name
--------- ---------- ----- ----
840 2018-11-26 17:27 source_folder/try.pl
6651 2018-06-01 13:02 source_folder/url
--------- -------
7491 2 files
看起来你正在Windows上工作。你能试试这个:
zip\@files=>“$zip”,FilterName=>sub{s}\Q$cwd\\\\\\\\\\\\\}或者死“zip失败:$ZipError\n”代码>您是否查看了替换的结果s
使您完全没有文件夹结构,因为它贪婪地吞噬所有内容,直到最后一个反斜杠。也许您只想从$File::Find::name
的开头删除length$cwd
字符?请编辑您的帖子,并向我们展示具体的输入文件名、您得到的输出文件名、您想要的输出文件以及您想要的结果zip结构。@GMB这与我代码第一部分中使用的方法不同吗?s |\Q$cwd\\\|
替换将删除工作目录,但会留下一对//将其转换为windows资源管理器“不可见”的初始文件夹。我可以用7zip或类似的工具查看它们,但是,运行该工具的系统需要它们在windows中可见。@Corion,我意识到这是贪婪地删除了整个路径。我尝试了使用子字符串zip\@files=>“$zip”,FilterName=>sub{substr($\u0,length($cwd))}或die“zip失败:$ZipError\n”的length$cwd方法代码>。不幸的是,这给了我与s|\Q$cwd\\\|
相同的结果。我将尝试找到一种方法来呈现结果。嗨@clamp,请您呈现最终zip文件的结果好吗?这是我提供的代码,它不会在windows中使用附加的打印语句生成可行的结果。已排序!非常感谢。所以,我有压缩工作,但我有一个问题,有2个文件报告为损坏时,他们被提取。这些文件是.xlsx和.pdf文件。我是否应该应用特定的设置来防止这种情况发生?请尝试将binmode=>1添加到压缩线。因此变成了zip\@files=>“$zip”,BinModeIn=>1,FilterName=>sub{s |\Q$cwd |}谢谢你,并为超级延迟的响应道歉。我刚刚用这个额外的参数更新了代码,它工作得非常好。