单行 Perl
Table of Contents
Perl 尤其擅长用一行代码来解决问题。
首先学习几个 perl 命令的参数,并牢记:
-a:分隔行,并保存到 @F 变量中 -F:配合 -a,指定分隔符 -i:结果直接替换当前文件,如果要备份原始文件,就在 -i 后面直接跟上扩展名,如 -ibak -n:逐行处理文件 -p:类似 -n,但会打印每一行 -e:执行的 Perl 代码 -l:打印时添加换行符(就不用显示在代码中增加 \n 了) -C:如果要在代码里使用 UTF-8 字符集,就使用该参数
替换字符串,将 root 替换为 ROOT:
$ perl -pe 's/root/ROOT/g' /etc/passwd
打印匹配到行,类似 grep:
$ perl -ne 'print if /nologin/' /etc/passwd
打印“oo”出现两次以上的行:
$ perl -ne 'print if (s/oo/oo/g >= 3)' /etc/passwd root:x:0:0:root:/root:/bin/bash
打印行号:
$. 保存了当前的行号。
$ perl -pe 'print "$. "' /etc/passwd
按列打印:
$ perl -F':' -ale 'print @F[0]' /etc/passwd 注:参数 -F 指定分割符
处理 CSV:
perl -a -F, -lne 'printf("@F[0],@F[1],@F[2],@F[3]\n")' file.csv -F 指定“,”为分隔符
1. BEGIN 和 END 块
前面介绍的单行代码,对每一行输入都会执行一次,有时有些代码只需要执行一次,比如初始化了某个变量或者示例。
例,取域名列表文件的二级域:
$ perl -MDomain::PublicSuffix -nle 'BEGIN{$s = Domain::PublicSuffix->new();}; $d = $s->get_root_domain($_); print $d if $d' all_domain
因为 Domain::PublicSuffix->new() 只需要执行一次,所以放到了 BEGIN 代码块中。
END 代码块是在读取文件完之后才执行,一般使用在统计场景中。