Perl的命令行编程


在Linux系统上进行操作,使用Perl有时候可以起到很好的效果(特别是在用Bash做起来比较复杂,Python的版本又太陈旧的时候),下面记录一些从网上找到的Perl命令行编程的教程:


-e 后面紧跟着引号里面的字符串是要执行的命令:

[email protected]:~$ perl -e 'print "hello world \n"'
hello world

如果是多个命令就可以使用多个-e选项,这里是不是想到了sed呢?但是要注意的是中间是用的”;”分隔。

[email protected]:~$ perl -e 'print "hello world \n";' -e 'print "my first perl command line script \n"'
hello world
my first perl command line script

-M 导入要使用的模块:

[email protected]:~$ perl -MLWP::Simple -e 'print head "http://ixyzero.com","\n"'
text/html; charset=UTF-8nginx

另外 -M 可以判断某个模块是不是已经安装了。

-m 的功能和 -M 类似,区别在于 -M 模块名等同于 use 模块名,这样会把一些默认的函数或者其它东西引进过来,-m 模块名 则会关闭这些默认值,这样可以只引入一些你要使用的函数;例如上面的例子:换成-m的话就不会有任何输出;-m 和 -M 通过 = 来引入某个模块的特别函数。

$ perl -MCGI='header,start_html' -e 'print header, start_html'
Content-Type: text/html; charset=ISO-8859-1

<!DOCTYPE html
        PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body>

-w 等同于use warnings

-n -p 都会使用 <> 将所有 @ARGV 参数当作文件来逐行运行(有循环的意思,经常和其它参数一起处理文件),会将读入的内容隐式的逐一按行来遍历文件。每一行将缺省保存在 $_ 但 -p 会将内容”重复”打印出来,而 -n 更倾向与打印满足某种条件的行(这这里还有一些有用的变量比如 $. 表示当前行的行号):

[email protected]:~$ cat file.txt
A 1
B 2
C 3
[email protected]:~$ perl -p -e 'print ' file.txt
A 1
A 1
B 2
B 2
C 3
C 3
[email protected]:~$ perl -n -e 'print ' file.txt
A 1
B 2
C 3

看到这里是不是想到了sed的 -n 的特性:

[email protected]:~$ sed -ne 'p' file.txt
A 1
B 2
C 3
[email protected]:~$ sed -e 'p' file.txt
A 1
A 1
B 2
B 2
C 3
C 3

-i 将修改直接的写入文件,这个和sed也是一样的哦;

[email protected]:~$ cat file.txt
A 1
B 2
C 3
[email protected]:~$ perl -pi -e 's/A/a/' file.txt
[email protected]:~$ cat file.txt
a 1
B 2
C 3

-a 打开自动分离 (split) 模式。空格是缺省的分离号,输入根据分离号被分离然后放入缺省数组 @F 。

[email protected]:~$ perl -na -e 'print $F[1],"\n"' file.txt
1
2
3

和awk是不是很像?还有更像的,那就是-F,和awk一样更改字段之间的分割符,默认是空格和tab;

[email protected]:~$ perl -F':' -alne 'print $F[0]," ",$F[-1] if /bash$/' /etc/passwd
root /bin/bash
postgres /bin/bash

看到上面的那个 -l 的参数没?它的最主要的作用就是 chomp 字段和在每个输出的后面加上”\n”输出换行,是不是挺有用的呢?

有没有其它和awk有类似的地方呢?答案是肯定的,BEGIN{},END{} 是不是也很熟悉呢?以下是一些常用的简单实例:

$ perl -pi -e's/aaa/bbb/' filename  #直接修改当前文件中的内容,不生成中间文件,一定要使用 -i 开关
$ perl -ne 'print if /^aaaaa/' filename #像grep一样过滤文件中需要的内容,这里使用了 -n 所以是一次做一行的操作,直到整个文件读完;另外;在使用管道时 -n 也会一样依次遍历管道送过来的内容
$ perl -n -e 'print "$. – $_"' filename #这里没用 -ne 而是写成了 -n -e ,但效果一样:给当前文件中的内容添加行号并打印。注:$. 表示当前行号
$ perl -pe '$_ = "$. $_"' filename  #这个其实和上面一样,只是使用 -p 替换了 -n ,这个有个什么好处呢?别的地方都一样,但 -p 按行遍历完文件后,会将 $_ 打印出来

大家还记得awk分割域(awk ‘{i = NF – 1; print $1 + $i}’)么?下面我们来看看perl:

$ perl -lane 'print $F[0] + $F[-2]' #这里的技巧在于 -a ,使用 -a 将数据分割成@F的数组
$ perl -ne 'print if /^START$/ .. /^END$/'  #打印正则中从 START 到 END 的地方
$ perl -ne 'print if $. >= 15; exit if $. >= 17;'   #有效地打印数字范围中的行
$ perl -p -i.bak -e 's/\bfoo\b/bar/g' *.c   #原地修改 -i 开关的神奇之处在于它对 @ARGV 中的每个文件都用该脚本对每个文件输出所产生的文件内容进行替换
$ perl -ne 'print scalar reverse $_' filename   #对文件中的内容反向排序,比如文件中有abc,就会打印出cba
参考链接:
,

《“Perl的命令行编程”》 有 1 条评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注