Perl单行中的每一个都会发生什么?

时间:2014-02-01 13:26:22

标签: regex perl command-line-interface

我试图理解cli中的perl一个衬里 例如,如果我需要在文件中进行替换:

perl -e 's/eat/read/g' file  

什么都没发生。

如果我这样做:

perl -i -e 's/eat/read/g' file

文件也没有任何反应。

只有我这样做:

perl -p -i -e 's/eat/read/g' file

文件中的替换内联发生 如果我做

perl -n -i -e 's/eat/read/g' file

文件变空了!

有人可以解释一下这些差异以及每种情况会发生什么吗?

2 个答案:

答案 0 :(得分:8)

B::Deparse模块将显示哪些开关对您的perl代码执行了哪些操作,

perl -MO=Deparse -e 's/eat/read/g' file
s/eat/read/g;

这里没什么有趣的,你的代码按原样执行。

perl -MO=Deparse -i -e 's/eat/read/g' file
BEGIN { $^I = ""; }
s/eat/read/g;

好的,-i更改了全局变量$^I以进行内联编辑,但没有正在读取的文件,也没有循环。

perl -MO=Deparse -p -i -e 's/eat/read/g' file
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
    s/eat/read/g;
}
continue {
    print $_;
}

所以-p添加while(){}循环,其中每行都被读取,由您的代码更改,并再次写入文件(在continue{}块中打印)

perl -MO=Deparse -n -i -e 's/eat/read/g' file
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
    s/eat/read/g;
}

所以-n没有像continue{}开关一样阻止-p阻止,如果你想对s///进行替换,你必须手动打印该文件(否则没有打印任何内容,你的文件会因为你已经注意到而被截断)。

答案 1 :(得分:2)

摘录自perl -h

Usage: perl [switches] [--] [programfile] [arguments]
  -e program        one line of program (several -e's allowed, omit programfile)
  -i[extension]     edit <> files in place (makes backup if extension supplied)
  -n                assume "while (<>) { ... }" loop around program
  -p                assume loop like -n but print line also, like sed

在原地-i编辑文件时,您还需要使用-p或明确(使用-n's/eat/read/; print'

将某些内容打印到文件中

就地编辑的常见模式是

perl -pi.bak -e 's/eat/read/g' file

将按预期修改您的文件,保存后缀为.bak

的备份