我的文件包含lin.txt和lin1.txt等文件名以及其他.txt文件。我只需找到这些文件并仅打印一个文件。我有下面的代码,但它不知道匹配以lin *开头的文件。有什么问题?
$te_dir= "/projects/xxx/";
opendir (DIR, $te_dir) or die $!;
while (my $file = readdir(DIR))
{
if ($file=~/\.txt/)
{
#// Doing some tasks.
if($file ~= 'lin*.txt')
{
$linfile=$te_dir/$file;
open(LINFILE, $linfile) or die "Couldn't open file $file:$!";
while(my $line = <LINFILE>)
{
print $line;
}
close LINFILE;
}
}
}
答案 0 :(得分:3)
您正在将globs(shell通配符)与正则表达式混合使用。这是两种不同的形式,具有不同的语法和语义。在正则表达式中(这是Perl匹配使用的),n*
匹配零个或多个字符n
。你可能意味着
if ($file =~ /lin.*\.txt/)
还要注意运算符中的语法错误。您在第一个条件中正确拥有=~
,但是您将其拼错为~=
,您可以在此进行比较。 (也许这只是一个转录错误;对我来说,这会产生一个明确的语法错误,所以脚本不会首先运行。)
如@brianadams的回答所述,正确的正则表达式是
if ($file =~ /^lin.*\.txt$/)
行^
的开头和行$
行的结尾以阻止例如来自匹配的feline.txt.html
。 Perl正则表达式的默认行为是在输入字符串中的任何位置找到匹配项。
答案 1 :(得分:1)
匹配以lin
if ( $file =~ /^lin.*\.txt$/ )
答案 2 :(得分:1)
这是对代码的快速(和最小)重写可能会有所帮助:
use strict;
use warnings;
my $te_dir = "/projects/xxx/";
opendir( my $dirh, $te_dir ) or die "Could not open '$te_dir': $!";
while ( my $file = readdir($dirh) ) {
next unless $file =~ /\.txt$/;
#// Doing some tasks.
if ( $file =~ /^ lin \d* \.txt $/x ) {
my $linfile = "$te_dir/$file";
open( my $fh, $linfile ) or die "Couldn't open file $linfile: $!";
while ( my $line = <$fh> ) {
print $line;
}
close $fh or die "Could not close $linfile: $!";
}
}
首先,请注意我们已将strict
和warnings
放在代码的顶部。这将告诉你各种有趣的问题,包括拼写错误的变量名称。
接下来,我们切换到词汇句柄(例如,my $dirh
而不是DIR
)。您正在使用的句柄的“裸字”版本(DIR
和LINFILE
已经被劝阻了很长一段时间,因为这些是有效的全局构造,并且通常全局数据很糟糕,因为当它被破坏时,它是很难说是什么打破了它,所以我们更喜欢词汇版本(用my
内置声明的句柄。)
此外,这条线你可能没有按照你的想法行事:
$linfile=$te_dir/$file;
你试图用正斜杠粉碎目录和文件名,但由于你没有使用字符串插值,你实际上是在使用 division 。在这个数字上下文中,你的导演和文件名都可能会评估为零,当你试图打开一个文件时,会给你一个除零错误!
但是,如果您愿意使用CPAN模块,则可以更轻松地实现这一目标:
use strict;
use warnings;
use File::Find::Rule;
my $te_dir = "/projects/xxx/";
my @files = File::Find::Rule->file->name('lin*.txt')->in($te_dir);
foreach my $linfile (@files) {
#// Doing some tasks.
open my $fh, $linfile or die "Couldn't open file $linfile: $!";
while ( my $line = <$fh> ) {
print $line;
}
}
没有麻烦,没有大惊小怪。在第一遍中只获取您想要的文件,并且已经拥有正确的文件名(请注意,我没有关闭文件句柄,因为当$fh
超出{{1}末尾的范围时,它会自动关闭循环。)
答案 3 :(得分:0)
尝试从此处更改第二个if
条件,
if($file ~= 'lin*.txt')
到此,
if($file =~ /lin*\.txt/)
您也可以尝试:if($file =~ /^lin*\.txt/)
,正如其他答案中已经指出的那样,但您需要确保$file
变量中存储的文件名只包含文件名而不是整个路径。