序:内容取自 《Perl One-Liners》,注意该教程中示例的 ' 符号(单引号)在windows 中应改为双引号,否则不会奏效。我在翻译和摘录的代码中也会改用双引号
备注:
- 1. 不做全文翻译,尽量简明
2. 假设看官已经有正则表达式基础
3. 环境:Win7, Strawberry Perl 5.24 Portable Edition
- 第一个示例,全局将文件中的 you 替换为 me:
- perl -pi -e "s/you/me/g" file
/g 表示全局替换
-e 参数允许执行 Perl 代码
-p 参数确保处理文本的每一行并且将处理后的结果打印出来
-i 参数将修改的结果应用到文件中(所以看不到 -p 打印的内容了)
-i[extension] edit <> files in place (makes backup if extension supplied)
注意,实际测试 -i 参数必须提供扩展名以备份文件,否则提示:Can't do inplace edit without backup.
perl -pi.bak -e "s/you/me/g" file
- perl -pi.bak -e "s/you/me/g" file1 file2 file3
- perl -pi.bak -e "s/you/me/g if /we/" file
- perl -ne "print if $a{$_}++" file
$_ 表示当前遍历的行的内容
-n 表示遍历所有行(类似 -p 但不负责打印结果)
执行后将自动建立字典 %a,当 $_ 对应的值第一次出现的时候,$a{$_} 还是 undef(同0),+1在下次生效。再次出现时为1,打印输出,以此类推。
- perl -ne "print \"$. $_\"" file
在 Perl 中,$. 是一个特殊变量,表示当前行数。这个例子也可以改用 -p
perl -pe "$_ = \"$. $_\"" file
- perl -ne "print \"$. $_\" if $a{$_}++" f.txt
- perl -MList::Util=sum -alne 'print sum @F' f.txt
说明:
-MList::Util 导入 List::Util 模块
=sum 表示导入 List::Util 的 sum 函数
-a 参数,自动按空格划分行的内容并保存到 @F,使单词、数字独立出来
注 -F/pattern/ 参数可指定其他划分规则
-l 参数确保每一次输出都换行,省了手动 "\n"
- perl -MPOSIX -le "@t = localtime; $t[3] -= 1299; print scalar localtime mktime @t"
实际时间:
Wed Apr 26 19:31:22 2017
输出:
Sat Oct 5 19:31:22 2013
这个过程实际就是 用 @t 获取 localtime 的返回结果(数组环境),将日期减1299(在数组成员中会变成负数),再使用 mktime 将其封装,返回给 localtime,再用标量环境打印 localtime 的返回值
- perl -le "print map { ('a'..'z')[rand 26] } 1..8"
1..8 产生数组数字从 1-8,关键是产生8次循环
('a'..'z') 产生数组元素a-z,而 [rand 26] 随机产生数组下标,也就是随机选取字母
map 返回每一次循环的处理结果
要我写的话可能会用 grep ,逐个 print
perl -e "grep { print (('a'..'z')[rand 26]) } (1..8)"
发现 print ('a'..'z')[rand 26] 会提示语法问题,必须外加括号。
- perl -lane "$sum += $F[0]; END { print $sum }" f.txt
END {} 定义了一个代码块,该代码块在脚本结束时运行
如果对 perl 的任一项参数有疑惑,可以参考
perldoc perlrun
其他参考
perldoc perlvar - 关于 Perl 的特殊变量
perldoc perlop - 操作符
perldoc perlfunc - 函数
- perl -pi -e "s/you/me/g" file