6

我正在尝试从目录中压缩文件。它工作得很好,除非文件名有空格。

由于glob将其参数拆分为空格,因此我也尝试过bsd_glob,但没有成功。

如何处理文件名中的空格?我正在寻求检索所有文件。

#Directory of focus
my $log = 'C:/Users/me/Desktop/log';

my @files = bsd_glob( $log.'/*.*' );

#Copy contents to new directory to be zipped
foreach my $file (@files) {
   copy($file, $logout) or die
   "Failed to copy $file: $!\n";
}

复制失败

# Create Child tmp
my $out = 'C:/Users/me/Desktop/out';
mkdir $out;

# Directory of focus
my $log = 'C:/Users/me/Desktop/log';

opendir (DIR, $log) or die $!;

while ( my $file = readdir(DIR) ) {
    next if $file =~ /^\./;
    #print "$file\n";
    copy($file, $out) or die "Failed to copy $file: $!\n";
}

closedir (DIR);
4

2 回答 2

6

您的代码中没有任何冲突,因为空格在 glob找到的文件中无关紧要,仅在您作为参数传递给它的模式中。我注意到你在评论马特雅各布的帖子

对不起,这个过程有效。谢谢!显然该文件在其他地方打开

所以我想这一直是问题所在。但我认为如果我解释如何glob处理包含空格的模式会很有用

glob带空格的行为

我会写

my @files = glob "$log/*.*"

因为我认为它更清晰,但是您传递给的字符串glob没有C:/Users/me/Desktop/log/*.*空格,所以glob很好

如果您在某处的路径中有一个空格,那么您是对的 -glob将在这些空格处拆分并将每个部分视为一个单独的参数。说你有

my @files = glob "C:/Program Files/*"

那么您将获得该列表('C:/Program'),因为glob仅当模式中存在通配符时才检查文件是否存在。所以我们取回了C:/Program没有通配符的第一部分,但第二部分没有更多贡献,因为没有匹配的文件Files/*

使用引号的解决方案

在这种情况下,解决方案是将包含空格的模式包含在一对引号中——单引号或双引号。所以无论是

my @files = glob "'C:/Program Files/*'"

或者

my @files = glob '"C:/Program Files/*"'

会正常工作。但是如果你想插入一个像你这样的路径,C:/Users/me/Desktop/out那么最外面的引号必须是双引号。在你的情况下,看起来像

my $log = 'C:/Users/me/Desktop/log';
my @files = glob "'$log/*.*'";

qq但我更喜欢像这样使用替代运算符

my $log = 'C:/Users/me/Desktop/log';
my @files = glob qq{"$log/*.*"};

使用 bsd_glob 的解决方案

正如您在问题中指出的那样,替代方法是添加

use File::Glob 'bsd_glob'

到代码的顶部并改用该bsd_glob函数,它将模式中的空格与任何其他字符相同,并且不会拆分它们。

或者如果你有

use File::Glob ':bsd_glob'

(注意附加的冒号)然后标准glob调用的行为方式与 相同bsd_glob,这允许您使用尖括号形式glob像这样

my @files = <C:/Program Files/*>

没有任何问题

于 2015-08-28T02:32:57.630 回答
1

不要使用glob. 改为使用readdir(或File::Find如果需要递归)。

opendir (my $dh, $log) or die $!;

while (my $file = readdir($dh)) {
    next if $file =~ /^\./;
    copy("$log/$file", $out) or die "Failed to copy $file: $!\n";
}

closedir($dh);
于 2015-08-27T22:40:35.370 回答