我试图理解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
文件变空了!
有人可以解释一下这些差异以及每种情况会发生什么吗?
答案 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