Если вы хотите напечатать каждую строку из DATA
только один раз, если один или несколько шаблонов совпадают, вы можете использовать grep
. Обратите внимание, что использование \Q
для цитирования метасимволов regex в аргументах командной строки и использование массива @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?
Что должно произойти?