perl一行式程序系列文章:Perl一行式
本文用来收集Perl一行式中涉及到的一些选项、特殊变量的说明,可以用来做速查手册。
本文会逐渐更新。
第一次学Perl一行式时,请直接忽略本文内容,并直接从后面的示例部分开始看。本文会在每一个示例中解释出现的选项、变量、函数和语法。
一行式选项
perl一行式语法:
perl [-0aFlimMnps] -e 'EXPRESSION' ARGUMENTS
perl [-0aFlimMnps] -E 'EXPRESSION' ARGUMENTS
其中"-e"或"-E"选项用于指定待运行的表达式,它们之间的不同点在于"-E"会自动启用高版本功能特性,例如可以直接使用say()函数而无需先use 5.010;
。
可以指定多个-e/-E,但使用多个的时候,注意每个表达式后面的';'结尾符号,否则语法报错。
-n和-p
这两个选项都表示按照隐含的逻辑直接处理表达式后面的参数代表的文件。如果perl -e
命令行中没有这两个选项,则只能自己在-e表达式中编写读取文件、处理数据、输出/删除的代码逻辑。
-n选项使得perl单行命令以类似于如下代码的方式运行:
LINE:
while(<>){
...-e expression CODE HERE...
}
由于while中使用的是<>
,所以它会从@ARGV
中读取参数文件进行处理。
perl -n
就像sed -n
一样,表示禁止默认的输出。如果想要强制输出,只能在-e表达式中自行指定输出操作,例如print/say/printf。
-p选项使得perl单行命令以类似于如下代码的方式运行:
LINE:
while(<>){
...-e expression CODE HERE...
}continue{
print or die "-p destination: $!
";
}
perl -p
用于强制输出$_
,它会覆盖-n选项。
必须要注意的是-n和-p都采用<>
来读取文件,而它从文件中读取每一行时会保留每一行的尾随换行符"
"。
何时使用"-p",何时使用"-n"
-p和-n的逻辑虽然很简单,也如sed的-n和p命令类似,但对于初学perl一行式程序的人来说,仍然很容易迷惑,因为Perl是一门语言,perl一行式也一样可以写成一门简单的语言,这意味着几乎总是有多种一行式的方式实现一个需求。
例如,-p可以被-n + print
替代,-n、-p都可以被-e中的while(<>)
替代。
但既然perl一行式提供了-n和-p的选项,写perl一行式的时候自然应该追求精简化,让-e表达式的代码逻辑更简单。
根据我个人的总结:
- 只要不操作文件,就不需要-n和-p
- 当某些行不需要输出,或者需要被删除的时候,也就是说不需要输出所有行时,不应该使用-p,因为它默认会输出所有行
- 换句话说,如果需要输出所有行,就可以考虑使用-p
- 使用-p的时候,在-e表达式中只需操作
$_
,例如对$_
的赋值、s替换,此时不需要额外的print,但有些操作是可以隐藏$_
的,最常见的就是s替换命令
- 不使用-p的时候,几乎总是可以使用-n,这时需要在-e表达式中手动print
- 如果处理文件的需求实在复杂,那么不要-n和-p,自己在-e中写文件读取的逻辑。但这种情况很少,真的出现这种情况,一般写成Perl脚本更好
-l选项
-l
-lOCTNUM
选项开启自动行尾处理功能。它有两个过程:
- 和-n和-p一起使用的时候,将自动对输入行执行chomp剔除输入行终止符
- 将print的输出行分隔符变量
$
设置为OCTNUM的八进制数值,OCTNUM的ASCII字符将追加在输出的每一行行尾。如果省略了OCTNUM,则将$
设置为输入行分隔符变量$/
的值,通常是换行符
需要注意的是,省略OCTNUM的时候,也就是只有-l的时候,会在处理这个选项的那一刻就完成$ = $/
的赋值,所以对于-ln0e EXPRESSION
将进行两段赋值:
# 处理-l的时候
$ = $/;
# 处理-0的时候
$/ = ;
这使得输出行分隔符取输入行分隔符的值,并在之后修改输入行分隔符。
注意上面的-0选项不能直接放在-l选项后(也就是-l0ne
),这会产生歧义,认为0是-l选项的参数值,而不是-0选项。
一般来说,"-l"选项是用来为print函数追加换行符的,所以"-l"经常结合-n选项一起使用。例如:
$ perl -lne 'print' file.log
-0选项
设置输入行分隔符$/
:
-0[octal/hexadecimal]
-0
使得perl读取行时,以