Regex perl压缩没有工作目录文件路径的文件夹

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/[

我正在尝试将包含文件和子文件夹(包含文件)的文件夹压缩到一个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/[\\]/\//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 |}谢谢你,并为超级延迟的响应道歉。我刚刚用这个额外的参数更新了代码,它工作得非常好。