通常我们运行perl的方式是写一个perl脚本,然后运行(比如perl perlscriptfilename.pl)。但是很多情况下,我们希望更加快捷的方式,把perl脚本写在命令行里面直接运行。这种做法在我们的日常工作中常常碰到。举一个实际的例子,在production的机器上只安装了vi,vi有一个缺陷,如果文件中有的行特别长,vi就不能正常工作。现在我们要修改一个配置,把arrowpig=smart改成arrowpig=fool
perl -pi -e ‘s/arrowpig=smart/arrowpig=fool/’ config_filename
我们可以使用perldoc perlrun查看帮助。所有以这种命令行内嵌脚本方式运行的perl都要指定-e选项。这里的-p讲究很大,为什么命令行内嵌perl命令这么简介,其实本质上它是最常见的处理代码模板预定义好,然后管理员只需要在命令中输入小段代码,perl会自动将输入的代码插入到模板中去,然后运行。比如上面的这条替代命令。它相当去打开configuration_filename, 然后顺序读入每一行,看看有没有匹配字符串arrowpig=smart,如果有就替换成arrowpig=fool,然后将处理后的每一行写到一个新文件,最后将新文件覆盖原始文件。这样就完成了配置的修改。
我们先来看-p, 使用-p就相当于选择了下面的程序模板:
while (<>)
{
… # 我们填入的小段代码就被插入到这里
}
continue #continue代码块中的内容在下一次while()中的内容被evaluation之前执行
{
print; #打印默认值$_
}
如果我们使用perldoc perlop查看在线帮助,我们就知道
while(<>)
{
#这里是对每一行的处理代码
}
实际上相当于:
unshift(@ARGV, ‘-’) unless @ARGV; # @ARGV是输入参数列表,在arrowpig这个例子中就是只有一个参数config_filename
while ($ARGV = shift) # 依次取出每一个输入参数,如果是’-'就认为是标准输入。
{
open(ARGV, $ARGV); # 打开文件,如果没有输入参数,就相当于打开标准输入,$ARGV中保存文件句柄
while (<ARGV>) # 依次从ARGV句柄中读入每一行,保存在$_中,直到文件结束
{
… # 这里是对每一行的处理代码
}
}
所以说perl -p -e ‘#每一行的处理代码’ 参数1 参数2 … 就相当于:依次打开参数n对应的文件,如果没有参数就相当去打开标准输入,对打开的每一个文件,再依次读入每一行,对每一行执行我们在命令行上输入的代码,然后往默认输出上打印$_。
-i是可以带参数的,具体细节可以自己看在线文档,在arrowpig这个例子里是不带参数的。我们只要记得,在Unix上,不带参数的-i和-p一起使用,就相当于对文件进行in-place处理。
-n也是很常用的选项,其实-n和-p的唯一区别就是-n的时候没有continue块,所以-n不会打印$_。猜猜
perl -pi -e ‘s/arrowpig=smart/arrowpig=fool/’ config_filename
结果是什么?
答案:因为没有输出任何东西到新文件(新文件将会覆盖原始文件),结果是清空config_filename文件。这显然不是我们需要的。
其实常用的还有-a -l等等选项,今天就不说了。下一篇我会给出一些实际使用的例子帮助大家理解和记忆的。最后再说一下,可以使用
perldoc perlrun | less
来阅读在线帮助,这是最方便的方式。使用windows的同学可以下载一个Win32版本的less命令。