Perl 单行命令是 Perl 最强大、最实用的特性之一,它被誉为“瑞士军刀”,通过在命令行上调用 Perl,你可以快速完成各种文本处理任务,而无需编写一个完整的脚本文件。

下面我将从基础到高级,详细讲解 Perl 单行命令。
基本语法
Perl 单行命令的基本结构如下:
perl -[options] -e 'code' [inputfile(s)]
perl: 调用 Perl 解释器。-[options]: 一个或多个选项,用于控制 Perl 的行为。-e 'code': 这是核心。-e选项告诉 Perl 后面跟着的字符串是一段要执行的代码。单引号 强烈推荐使用,它可以防止你的 shell(如 Bash)对代码中的 , , 等特殊字符进行不必要的扩展。[inputfile(s)]: 可选,要处理的文件,如果不提供文件名,Perl 会从标准输入读取数据,这通常与管道 结合使用。
常用命令行选项
| 选项 | 全称 | 描述 |
|---|---|---|
-e |
execute |
执行后面的字符串作为 Perl 代码。单行命令的灵魂。 |
-n |
line |
“循环”模式,自动为每一行输入文件设置 $_ 变量,并执行 -e 中的代码。不自动打印。 |
-p |
print |
“打印”模式,和 -n 一样,但会在每次循环结束后自动打印 $_ 的内容。 |
-l |
line |
自动处理行尾符。-l 会自动将输入的行尾符(如 \n)去掉,并在输出时自动加上,常与 -n 或 -p 结合使用。 |
-a |
autosplit |
“自动分割”模式,和 -n 或 -p 一起使用时,会用空格分割 $_ 到数组 @F 中。 |
-F |
field |
指定 -a 模式下的分隔符。-F: 表示用冒号分割。 |
-i |
inplace |
“原地编辑”模式,直接修改输入文件,并用 .bak 备份原文件。-i.bak。危险操作,请谨慎! |
-M |
module |
加载指定的模块。-MData::Dumper。 |
-w |
warnings |
启用警告,建议始终使用。 |
-l |
strict |
强制使用 strict 模式,要求变量必须声明。强烈建议与 -w 一起使用。 |
最佳实践组合:
为了写出健壮的单行命令,推荐使用 -w 和 strict,这可以通过 -M 选项实现:
perl -Mstrict -Mwarnings -e '...'
核心模式:-n 和 -p
这两个选项是 Perl 单行命令的精髓,它们将代码包装在一个隐式的 while 循环中。

隐含的代码结构
当你使用 -n 或 -p 时,Perl 实际上在执行以下代码:
LINE: while (<>) {
# -e '...' 中的代码在这里
# ...
} continue {
print if /^/; # -p 模式会执行这一行,而 -n 不会
}
<>: 这是一个特殊的文件句柄,它会自动从命令行指定的文件或标准输入中逐行读取数据。$_: 默认情况下,读取的行会存储在$_这个“默认变量”中,很多函数和操作符都会默认作用于$_。
-n (循环但不打印)
当你只想对每一行执行某些操作,但不希望打印该行时,使用 -n。
示例 1:统计文件行数
这和 wc -l 的功能一样。
# -n 会循环每一行,但什么都不做,END 块在所有行处理完毕后执行。
perl -ne 'END { print "$.\n" }' filename.txt
- 这是一个 Perl 内置变量,表示当前是第几行(行号计数器)。
END { ... }: 这是一个特殊的代码块,会在程序正常结束时执行。
示例 2:打印包含 "error" 的行
这和 grep error 的功能一样。

# 只有当 $_ 中包含 "error" 时,才打印 $_ perl -ne 'print if /error/' filename.txt
print: 如果不给print提供参数,它会默认打印$_。/pattern/: 这是一个简单的模式匹配,$_匹配模式,则返回真。
-p (循环并打印)
当你想对每一行进行处理,并且希望打印处理后的结果时,使用 -p,这非常适合做“查找并替换”之类的操作。
示例 1:将所有 "foo" 替换为 "bar"
这和 sed 's/foo/bar/g' 的功能一样。
# -p 会自动处理行尾符,-p 会自动打印处理后的 $_ perl -pe 's/foo/bar/g' filename.txt
s/old/new/g: 这是 Perl 的替换操作符,全局替换。
示例 2:打印每行的第一个单词 假设用空格分割。
# -a 会自动将 $_ 分割到 @F 数组 # -p 会自动打印 $_,但我们想修改它,所以直接操作 @F[0] perl -ape '$_ = $F[0] . "\n"' filename.txt
-a: 启用自动分割。@F: 一个由空格分割$_而成的数组。$_ = ...: 我们重新赋值了$_,-p会打印这个新值。
-l 选项的妙用
-l 会自动处理行尾符,这在处理文本时非常方便。
场景: 你想将每一行的 "apple" 替换为 "orange",但又不希望丢失原有的换行符。
不使用 -l:
# 错误示范:会丢失换行符 $ echo "apple pie" | perl -pe 's/apple/orange/' orange pie⏎ # 注意,这里没有换行符,因为 s/// 操作移除了它
使用 -l:
# 正确示范:-l 会自动处理换行符 $ echo "apple pie" | perl -pe 's/apple/orange/' orange pie⏎ # 换行符被正确保留
-l 的工作原理是:
- 在读取行时,它自动移除
\n(并存储起来)。 - 在打印行时,它自动在末尾添加
\n。
-i 选项:原地编辑
-i 会直接修改文件,请务必小心使用,最好先备份。
语法: -i[extension]
示例: 在 config.txt 中将 "localhost" 替换为 "127.0.0.1",并备份原文件为 config.txt.bak。
perl -i.bak -pe 's/localhost/127.0.0.1/g' config.txt
执行后:
config.txt的内容已经被修改。config.txt.bak是修改前的config.txt的备份。
原地编辑并使用 -a (CSV 示例):
假设有一个 data.csv 文件,内容是 name,age,你想将所有人的年龄加 1。
Alice,30 Bob,25 Charlie,42
命令:
# -i.bak 备份文件 # -a 自动用逗号分割 # -F, 指定分隔符为逗号 # -l 自动处理行尾 # -p 循环并打印 perl -i.bak -alpe '$_ = $F[0] . "," . ($F[1] + 1)' data.csv
执行后 data.csv
Alice,31 Bob,26 Charlie,43
执行后 data.csv.bak 内容(原文件):
Alice,30 Bob,25 Charlie,42
实战技巧与示例
示例 1:计算文件中单词的平均长度
# -a 分割单词到 @F
# -n 循环但不自动打印
# map { length $_ } @F 计算每个单词的长度
# sum() 函数需要 List::Util 模块
# END 块在最后执行计算和打印
perl -MList::Util=sum -alne '$t += sum map {length} @F; $c += @F; END { printf "%.2f\n", $t/$c }' file.txt
示例 2:找出 UID 为 0 的用户
这和 awk -F: '$3 == 0 {print $1}' /etc/passwd 功能一样。
# -F: 指定冒号为分隔符 # @F[2] 是第三个字段 (UID) # -n 循环,print 只在条件满足时执行 perl -F: -ane 'print $F[0], "\n" if $F[2] == 0' /etc/passwd
示例 3:从 HTML 中提取所有链接
这需要 HTML::LinkExtor 模块,展示了 -M 的用法。
# -M 加载模块
# -n 循环
# HTML::LinkExtor->new 的回调函数收集链接
# map { @$_ } 将所有链接展平
# grep { /href/i } 筛选出 href 属性
# sort -u 排序并去重
perl -MHTML::LinkExtor -0777 -ne '
my @links;
HTML::LinkExtor->new(sub { push @links, @_; })->parse($_);
print join "\n", sort -u map { @$_ } grep { /href/i } @links;
' index.html
| 任务 | sed / awk / grep |
Perl 单行命令 |
|---|---|---|
| 打印匹配行 | grep pattern |
perl -ne 'print if /pattern/' |
| 替换文本 | sed 's/old/new/g' |
perl -pe 's/old/new/g' |
| 提取列 | awk -F, '{print $1}' |
perl -F, -ane 'print $F[0]' |
| 复杂逻辑 | awk '{if (...) ...}' |
perl -ane '{if (...) ...}' |
| 原地编辑 | sed -i.bak 's/.../.../' |
perl -i.bak -pe 's/.../.../' |
掌握 Perl 单行命令需要练习,但一旦你熟悉了 -n, -p, -a, -l, -i 这些选项,你将拥有一个极其强大的工具,能以惊人的速度解决各种文本处理难题。
