Perl继续让我感到惊讶。我有一个代码从命令行获取输入并检查它是否在文件中。我有这样一个文件:
LS
日期
PWD
触摸
RM
首先我把这个文件读成
open(MYDATA,"filename") or die "Can not open file\n";
@commandlist = <MYDATA>;
chomp @commandlist;
close MYDATA;
参数在$ commandname变量中。为了检查它是否正确,我打印到屏幕上。
print $commandname."\n";
效果很好。然后我写了代码。
$count = @commandlist;
for($i=0;$i < $count;$i++)
{
print $commandname;
print $commandlist[$i];
print "\n";
if($commandname eq $commandlist[$i])
{
print "equal\n";
}
}
并且它不打印'相等'。但它应该这样做,因为$ commandname变量具有文件中的值'ls'。我还打印$ commandname和$ commandlist [$ i]的值,看看它们是否“相等”,我得到了输出:
ls
lsls
lsdate
lspwd
lstouch
lsrm
在这里我看到他们得到了相同的值,但为什么永远不会将eq运算符计算为零。 另外为了完成这项任务,我尝试了各种方法,所有这些方法都变得毫无用处,比如从数组中创建哈希并使用exists。 我一天都在努力寻找这个看似简单的问题,但我只是不明白。 提前致谢
编辑: 当我改变上面的循环如下
$count = @commandlist;
for($i=0;$i < $count;$i++)
{
print $commandlist[$i];
print $commandname;
print "\n";
if($commandname eq $commandlist[$i])
{
print "equal\n";
}
}
我的输出就像。
ls
ls
lste
lsd
lsuch
ls
似乎由于某种原因它会覆盖一些角色。
编辑:
我的整个脚本就像:
#reading file code, i posted above
while(<>)
chomp($_);
$commandname = $_;
if($commandname eq "start"){
##something here
} elsif ($commandname eq "machines"){
##something here
} else {
$count = @commandlist;
for($i=0;$i < $count;$i++)
{
print $commandlist[$i];
print $commandname;
print "\n";
if($commandname eq $commandlist[$i])
{
print "equal\n";
}
}
}
答案 0 :(得分:3)
代码中的一点改变会导致你正在寻找的东西,在你把它用于比较之前,从数组中“扼杀”字符串。这是
chomp $commandlist[$i];
if($commandname eq $commandlist[$i])
{
print "equal\n";
}
编辑:根据perldoc chomp,当你选择一个列表时,你应该括号。所以,在你的情况下......而不是简单地说
chomp @commandlist
使其像
chomp(@commandlist)
最终编辑:我试过这个并且工作正常。试一试
$commandname = $ARGV[0];
open(MYDATA,"chk.txt") or die "Can not open file\n";
@commandlist = <MYDATA>;
chomp(@commandlist);
close MYDATA;
print $commandname."\n";
$count = @commandlist;
print $commandname;
for($i=0;$i < $count;$i++)
{
print $commandlist[$i];
print "\n";
if($commandname eq $commandlist[$i])
{
print "equal\n";
}
}
答案 1 :(得分:3)
重写表示存在CR。这些行以CR
LF
结尾,但您只能使用LF
删除chomp
。变化
while (<>) {
chomp($_)
到
while (<>) {
s/\s+\z//;
答案 2 :(得分:1)
您可以考虑将代码重构为:
my $path='filename';
my $match='ls';
open(my $fh, '<', $path) or die "failed to open $path: $!";
my @commandlist=<$fh>;
chomp @commandlist;
# or you can combine these lines as:
# chomp(my @commandlist=<$fh>);
# because chomp operates on the array itself rather than making a copy.
close($fh);
或
use File::Slurp qw/ read_file /;
# see http://search.cpan.org/dist/File-Slurp/lib/File/Slurp.pm
my @commandlist=read_file($path); # result is pre-chomped!
foreach my $command (@commandlist) {
print "$match equals $command\n" if $match eq $command;
}
一个重要的考虑因素是文件中的每一行必须只包含 命令名称,并且不能以任何空格或制表符开头或结尾。要补偿可能的前导或尾随空格,请尝试:
foreach my $command (@commandlist) {
$command=~s/^\s+|\s+$//g; # strip leading or trailing whitespace
print "$match equals $command\n" if $match eq $command;
}
最后,总是用Perl开发人员最好的朋友开始你的Perl脚本:
use strict;
use warnings;
将捕获由草率编程实践引起的大多数(如果不是全部)错误。 (我们都受此影响!)