Мне нравится думать о perl -n
как о выделении определенных битов ввода и perl -p
как map
для всех строк ввода.
Как вы заметили, эффект -p
можно получить с помощью -n
, а мы можем эмулировать наоборот:
$ echo -e "1\n2\n3" | perl -pe '$_="" if $_ % 2 == 0'
1
3
Пропуск строк с next
может показаться более естественным, но -p
заключает код в
LINE:
while (<>) {
... # your program goes here
} continue {
print or die "-p destination: $!\n";
}
По проекту next
работает continue
блоков:
Если есть continue
BLOCK, он всегда выполняется непосредственно перед тем, как условная оценка собирается снова быть оценена. Таким образом, его можно использовать для увеличения переменной цикла, даже если цикл был продолжен с помощью оператора next
.
Переключатель -l
имеет два полезных эффекта:
- С
-n
и -p
, автоматически chomp
каждая входная запись.
- Установите
$\
, чтобы каждый print
неявно добавлял терминатор.
Например, чтобы захватить первые 10 портов UDP, упомянутых в /etc/services
, вы можете
perl -ane 'print $F[1] if $F[1] =~ /udp/' /etc/services | head
но упс:
7/udp9/udp11/udp13/udp17/udp19/udp37/udp39/udp42/ud...
Лучше:
$ perl -lane 'print $F[1] if $F[1] =~ /udp/' /etc/services | head
7/udp
9/udp
11/udp
13/udp
17/udp
19/udp
37/udp
39/udp
42/udp
53/udp
Помните, что -n
и -p
также могут быть в строке shebang, поэтому, чтобы сохранить вышеупомянутый oneliner как скрипт:
#! /usr/bin/perl -lan
BEGIN {
@ARGV = ("/etc/services") unless @ARGV;
open STDOUT, "|-", "head" or die "$0: head failed";
}
print $F[1] if $F[1] =~ /udp/