标题:
[转载教程]
[连载]Perl 一句话代码示例 翻译+整理
[打印本页]
作者:
523066680
时间:
2017-4-26 21:06
标题:
[连载]Perl 一句话代码示例 翻译+整理
本帖最后由 523066680 于 2017-5-10 23:16 编辑
编辑/整理:523066680@163.com
序:内容取自 《Perl One-Liners》,注意该教程中示例的 ' 符号(单引号)在windows 中应改为双引号,否则不会奏效。我在翻译和摘录的代码中也会改用双引号
备注:
1. 不做全文翻译,尽量简明
2. 假设看官已经有正则表达式基础
3. 环境:Win7, Strawberry Perl 5.24 Portable Edition
Chapter 1 - Perl ONE-LINERS
第一个示例,全局将文件中的 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
仅处理含有"we"的行:
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
借用 List::Util 模块统计每行中出现的数字的和
perl -MList::Util=sum -alne '
print
sum
@F
' f.txt
说明:
-MList::Util 导入 List::Util 模块
=sum 表示导入 List::Util 的 sum 函数
-a 参数,自动按空格划分行的内容并保存到 @F,使单词、数字独立出来
注 -F/pattern/ 参数可指定其他划分规则
-l 参数确保每一次输出都换行,省了手动 "\n"
让时间回退到 1299 天前:
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 的返回值
如何生成8位随机字符密码?map 走起:
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 - 函数
作者:
523066680
时间:
2017-5-8 23:19
标题:
Chapter 2. 换行和间隔符
本帖最后由 523066680 于 2017-5-12 15:16 编辑
最近是 真·工作繁忙,只能拖延了。(前几天逛亚马逊发现 Fluent Python 即将出中文版,价格过百,从目录来看干货蛮多(哦 这里是 Perl 区))
Chapter 2 - 换行和间隔符
在每行的末尾增加空白行
perl -pe "
$
\
=
\"\n\"
" f.txt
之前对 -p 和 -e 参数做过简要的说明,以上代码相当于:
while
(<>) {
$
\
=
"
\n
"
;
}
continue
{
print or die
"-p failed: $!
\n
"
;
}
构成
-p 参数建立 while (<>) {} continue { print } 循环结构
在 while 循环内默认用 $_ 存储当前读入的行,而 print 的缺省参数为 $_
-e "代码" 对应 while 循环内的代码。
continue 语句块在 while 的每次循环末尾继续执行,
特点是 continue {} 的代码不会因为 next 而跳过
特殊变量 $\ 相当于 AWK 中的 ORS 变量 (Output Record S eparator) 。
$\ 的内容将自动追加到 $_ 的末尾。循环地为 $\ 赋相同的值是不必要的,
将其放在 BEGIN 代码块可以节省开销(BEGIN代码块优先执行):
perl -pe "
BEGIN
{ $
\
=
\"\n\"
}
" f.txt
相当于:
BEGIN
{ $
\
=
"
\n
"
}
while
(<>) {
}
continue
{
print or die
"-p failed: $!
\n
"
;
}
其他方案
通过 "." 操作符添加换行:
perl -pe "
$_
.=
\"\n\"
" f.txt
或者使用s///正则替换:
perl -pe '
s/$/\n/
' f.txt
甚至可以利用 say 操作符的特性(Perl 5.10 或以上):
perl -nE '
say
' f.txt
-E 参数允许打开所有 Perl 的可选特性(为了支持 say 操作符)
-n 参数类似 -p ,遍历所有读入的行但不主动 print(前面介绍过了)
say 操作符类似 print,但 say 总是在每行的末尾添加 "\n"
最后,别忘了多用 perldoc, 执行 perldoc perlrun 查看perl命令行参数的详细说明
换行加倍,空行除外
perl -pe "
$_
.=
\"\n\"
unless
/^$/
" f.txt
unless 在 perl 中是 if not 的意思
/^$/ 表示行的开头和末尾之间没有其他字符
也可以用 \S 筛选:
perl -pe "
$_
.=
\"\n\"
if
/\S/
" f.txt
\s 代表一系列空白符号
\S 表示空白以外的字符
如果一行中包含空给以外的字符,则追加 \n
三倍换行符
相信各位已经能举一反三,不解释了(后面的命令行示例省去文件名部分)
perl -pe "
$
\
=
\"\n\n\"
"
perl -pe "
$_
.=
\"\n\n\"
"
perl -pe "
s/$/\n\n/
"
N倍换行符
Perl 使用 "字符"x数字 的方式对字符串翻倍叠加,例如7个换行符:`"\n"x7`
在每行之前添加空行
使用正则替换向文件开头插入\n:
perl -pe '
s/^/\n/
'
删除空白行
perl -ne '
print
unless
/^$/
'
由于这里要自己判断(筛选)输出,所以使用 -n 而非 -p
[Finished in 0.8s]
作者:
happy886rr
时间:
2017-5-9 00:42
回复
2#
523066680
很有实用价值,不过代码少了彩色高亮。
欢迎光临 批处理之家 (http://bbs.bathome.net/)
Powered by Discuz! 7.2