use strict;
use warnings;
my $numArgs = $#ARGV + 1;
print "thanks, you gave me $numArgs command-line arguments.\n";
while (my $line = <DATA> ) {
foreach my $argnum (0 .. $#ARGV) {
if ($line =~ /$ARGV[$argnum]/)
{
print $line;
}
}
}
__DATA__
A
B
Hello World :-)
Hello World !
当我通过一个arg时,效果很好。
比如我运行 test.pl A 或 test.pl B 或** test.pl Hello“
当我通过两个args时,它只运行一段时间。
成功:当我运行 test.pl A B 或 test.pl A Hello 或** test.pl B Hello“
失败:当我运行 test.pl Hello World *
时制作并输出重复的行:
D:\learning\perl>t.pl Hello World
thanks, you gave me 2 command-line arguments.
Hello World :-)
Hello World :-)
Hello World !
Hello World !
D:\learning\perl>
如何解决?感谢您阅读和回复。
[更新] 我不想打印重复的行。
答案 0 :(得分:3)
我没有看到问题,你的脚本处理__DATA__
并测试所有输入字:由于“Hello”和“World”每次匹配两次,它会打印4行。
如果您不希望它写多行,只需在last;
语句后添加print
。
答案 1 :(得分:3)
您获得重复输出的原因是因为正则表达式$line =~ /Hello/
匹配“Hello World”行,$line =~ /World/
也匹配“Hello World”行。为防止这种情况发生,您需要添加一些内容以记住__DATA__
部分中的哪些行已经打印过,这样如果它们与另一个参数匹配,您可以跳过它们。
另外,一些非常轻微的风格清理:
#!C:\Perl\bin\perl.exe
use strict;
use warnings;
my $numArgs = @ARGV;
print "thanks, you gave me $numArgs command-line arguments.\n";
while (my $line = <DATA> ) {
foreach my $arg (@ARGV) {
if ($line =~ /$arg/)
{
print $line;
}
}
}
__DATA__
A
B
Hello World :-)
Hello World !
在标量上下文中使用数组会返回其大小,因此$size = @arr
优先于$size = $#arr + 1
如果您不打算使用计数器进行索引而不是通过数组(for $i (0..$#arr) { $elem = $arr[$i]; ... }
)进行索引,那么只需循环遍历数组就更简单,更简单({{1} })。
您的for $elem (@arr) { ... }
循环也可以替换为foreach
语句,但我会将其作为练习留给读者。
答案 2 :(得分:1)
假设您只想在一个或多个模式匹配时从DATA
打印每一行,您可以使用grep
。请注意,使用\Q
在命令行参数中引用正则表达式元字符,并使用@patterns
数组预编译模式。
大声朗读if grep { $line =~ $_ } @patterns
:如果$line
匹配一个或多个模式; - )
#!/usr/bin/perl
use strict; use warnings;
printf "Thanks, you gave me %d command line arguments.\n", scalar @ARGV;
my @patterns = map { qr/\Q$_/ } @ARGV;
while ( my $line = <DATA> ) {
print $line if grep { $line =~ $_ } @patterns;
}
__DATA__
A
B
Hello World :-)
Hello World !
以下是有关您的脚本的一些评论,可以帮助您了解:
my $numArgs = $#ARGV + 1;
print "thanks, you gave me $numArgs command-line arguments.\n";
命令行参数位于@ARGV
(请阅读文档)。在标量上下文中,@ARGV
计算该数组中元素的数量。因此,您只需使用:
printf "Thanks, you gave me %d command line arguments.\n", scalar @ARGV;
此外,您可以直接遍历@ARGV
循环中foreach
的元素,而不是索引访问。
while (my $line = <DATA> ) {
foreach my $arg ( @ARGV ) {
if ( $line =~ /$arg/ ) {
print $line;
}
}
}
现在,如果我在命令行上将(
传递给你的程序会怎么样?或者,即使World?
会发生什么?