我最近开始使用Perl作为教育课程的要求。我们的部分功课是打开文本文件,读取一些行,然后关闭文件。
我在桌面上创建了一个文件夹,并将所需的文本文件放入其中。我编写了以下代码来打开每个文件,读取一行并关闭它:
my $dir = 'C:\Users\Jay Zabaluski\Desktop\Shakespeare';
opendir (DIR, $dir) or die "cannot opendir $dir";
foreach my $fp (glob("$dir/*.txt")) {
printf "%s\n", $fp;
open my $fh, "<", $fp or die "can't read open '$fp': $OS_ERROR";
my $firstLine = <$fh>;
print "$firstLine\n";
close $fh or die "can't read close '$fp': $OS_ERROR";
}
当我在Padre,Perl IDE上运行此脚本时,我收到此错误:
C:./UsersJay
can't read open 'C:./UsersJay': at example.pl line 5
Press any key to continue.....
我不明白为什么我收到此错误,除非我错误地使用\
而不是/
,但是当我在Windows资源管理器中右键单击某个文件时,路径总是出现反斜杠,例如C:\something\something
。
我尝试按照注释中的OnlineCop的建议更改文件路径以使用正斜杠,但得到了类似的错误:
C:/Users/Jay
can't read open 'C:/Users/Jay': at example.pl line 5
Press any key to continue.....
答案 0 :(得分:3)
正如其他人所观察到的那样,问题在于您拨打glob
glob("$dir/*.txt")
使用$dir
my $dir = 'C:\Users\Jay Zabaluski\Desktop\Shakespeare';
所以这个电话等同于这个
glob('C:\Users\Jay Zabaluski\Desktop\Shakespeare/*.txt')
所以参数有两个组件,C:\Users\Jay
和Zabaluski\Desktop\Shakespeare/*.txt
,这完全不是你想要的。
解决方案是将整个通配符模式用双引号括起来,这样你就可以使用qq
运算符来定义一个与"
不同的新分隔符,它将插入嵌入变量。
例如,尝试
my $glob_pattern = qq{"$dir/*.txt"};
say $glob_pattern;
你会看到传递给glob
的参数实际是
"C:\Users\Jay Zabaluski\Desktop\Shakespeare/*.txt"
包括双引号,这是必不可少的。
答案 1 :(得分:2)
foreach my $fp (glob qq("$dir/*.txt")) {
perldoc -f glob
:
Note that "glob" splits its arguments on whitespace and treats
each segment as separate pattern. As such, "glob("*.c *.h")"
matches all files with a .c or .h extension. The expression
"glob(".* *")" matches all files in the current working directory.
If you want to glob filenames that might contain whitespace,
you'll have to use extra quotes around the spacey filename to
protect it. For example, to glob filenames that have an "e"
followed by a space followed by an "f", use either of:
@spacies = <"*e f*">;
@spacies = glob '"*e f*"';
@spacies = glob q("*e f*");
If you had to get a variable through, you could do this:
@spacies = glob "'*${var}e f*'";
@spacies = glob qq("*${var}e f*")