使用Perl glob在模式中使用空格

时间:2015-08-27 22:31:37

标签: perl activestate

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

由于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);

2 个答案:

答案 0 :(得分:4)

您的代码中没有任何冲突,因为在找到的文件中,空格无关紧要,只有在您作为参数传递给它的模式中。我注意到您在Matt Jacob's post

上写了评论
  

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

所以我想这一直是问题所在。但我认为如果我解释如何让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/*>

没有任何问题

答案 1 :(得分:0)

请勿使用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);