我正在尝试从目录中压缩文件。它很有效,除非文件名有空格。
由于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);
答案 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/*.*"};
正如您在问题中指出的那样,替代方案是添加
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);