# add first and penultimate columns
# NOTE the equivalent awk script:
# awk '{i = NF - 1; print $1 + $i}'
perl -lane 'print $F[0] + $F[-2]'
那么这个小程序做了什么呢?几个开关是其神奇所在。 -n 开关和 -a 开关使该脚本成为对输入的包装器,该包装器根据空格将输入组成 @F 数组; -e 开关对该包装器额外添加了一条语句。实际产生的有趣代码是:
while (<>)
{
@F = split(' ');
print $F[0] + $F[-2]; # offset -2 means "2nd to last element of the array"
}
另一个常见任务是打印两个标记之间或两个行号之间的文件内容。
# 1. just lines 15 to 17
perl -ne 'print if 15 .. 17'
# 2. just lines NOT between line 10 and 20
perl -ne 'print unless 10 .. 20'
# 3. lines between START and END
perl -ne 'print if /^START$/ .. /^END$/'
# 4. lines NOT between START and END
perl -ne 'print unless /^START$/ .. /^END$/'
# 1. command-line that reverses the whole input by lines
# (printing each line in reverse order)
perl -e 'print reverse <>' file1 file2 file3 ....
# 2. command-line that shows each line with its characters backwards
perl -nle 'print scalar reverse $_' file1 file2 file3 ....
# 3. find palindromes in the /usr/dict/words dictionary file
perl -lne '$_ = lc $_; print if $_ eq reverse' /usr/dict/words
# 4. command-line that reverses all the bytes in a file
perl -0777e 'print scalar reverse <>' f1 f2 f3 ...
# 5. command-line that reverses each paragraph in the file but prints
# them in order
perl -00 -e 'print reverse <>' file1 file2 file3 ....
# 1. Run basename on contents of file
perl -pe "s@.*/@@gio" INDEX
# 2. Run dirname on contents of file
perl -pe 's@^(.*/)[^/]+@$1n@' INDEX
# 3. Run basename on contents of file
perl -MFile::Basename -ne 'print basename $_' INDEX
# 4. Run dirname on contents of file
perl -MFile::Basename -ne 'print dirname $_' INDEX
# 1. write command to mv dirs XYZ_asd to Asd
# (you may have to preface each '!' with a '' depending on your shell)
ls | perl -pe 's!([^_]+)_(.)(.*)!mv $1_$2$3 u$2E$3!gio'
# 2. Write a shell script to move input from xyz to Xyz
ls | perl -ne 'chop; printf "mv $_ %sn", ucfirst $_;'
下面并不是一个一行程序,但它是个相当有用的脚本,它在刚出现时充当一行程序。它与清单 7 的相似之处在于它替换了固定字符串,但诀窍在于替代该固定字符串的字符串本身在下次替换时又成了固定字符串。这个想法来自很久以前某个新闻组上的一个贴子,但我没能找到其最初版本。倘若您要在您所有系统文件中对一个 IP 地址用另一个 IP 地址替代(例如,如果您缺省的路由器已更改了),则该脚本很有用。该脚本在要重写的文件列表中包含 $0 (在 UNIX 中,通常是脚本的名称)。这个脚本作为一行程序来说,最终被证实太复杂,所以在要修改系统文件时,需要提供有关要执行什么的消息。
#!/usr/bin/perl -w
use Regexp::Common qw/net/; # provides the regular expressions for IP matching
my $replacement = shift @ARGV; # get the new IP address
die "You must provide $0 with a replacement string for the IP 111.111.111.111"
unless $replacement;
# we require that $replacement be JUST a valid IP address
die "Invalid IP address provided: [$replacement]"
unless $replacement =~ m/^$RE{net}{IPv4}$/;
# replace the string in each file
foreach my $file ($0, qw[/etc/hosts /etc/defaultrouter /etc/ethers], @ARGV)
{
# note that we know $replacement is a valid IP address, so this is
# not a dangerous invocation
my $command = "perl -p -i.bak -e 's/111.111.111.111/$replacement/g' $file";
print "Executing [$command]n";
system($command);
}