单行 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 代码块是在读取文件完之后才执行,一般使用在统计场景中。