这有效:
perl -pi -e 's/abc/cba/g' hellofile
但这不是:
perl -pie 's/cba/abc/g' hellofile
换句话说-pi -e可以工作,但-pie没有。为什么呢?
答案 0 :(得分:15)
-i
标志带有一个可选参数(如果存在,必须紧跟在它之后,而不是在单独的命令行参数中),该参数指定附加到输入文件名称的后缀。创建备份的目的。编写perl -pie 's/cba/abc/g' hellofile
会导致e
被视为此后缀,并且由于e
未被解释为普通-e
选项,Perl会尝试运行位于s/cba/abc/g
,可能不存在。
答案 1 :(得分:9)
由于-i
为备份文件提供了可选扩展名,例如-i.bak
,因此-i
之后无法直接跟踪其他标记。
-i [延伸]
指定由<>处理的文件构造将被编辑 到位。它通过重命名输入文件,打开输出来完成此操作 按原始名称输入文件,并选择该输出文件作为 print()语句的默认值。扩展(如果提供)用于 修改旧文件的名称以制作备份副本,如下所示 规则:
如果未提供扩展,则不进行备份,当前文件为 覆盖。
如果扩展名不包含*,则将其附加到末尾 当前文件名作为后缀。如果扩展名确实包含一个 或更多*字符,然后每个*被当前替换 文件名。在Perl术语中,您可以将其视为:
答案 2 :(得分:6)
perl已经告诉你为什么:) T ry- 我 t- T o- S ee < / p>
$ perl -pie " s/abc/cba/g " NUL
Can't open perl script " s/abc/cba/g ": No such file or directory
如果您使用B :: Deparse,您可以看到perl如何编译代码
$ perl -MO=Deparse -pi -e " s/abc/cba/g " NUL
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
s/abc/cba/g;
}
continue {
die "-p destination: $!\n" unless print $_;
}
-e syntax OK
如果你在perlvar中查找$ ^ I,你可以了解-i开关:)
$ perldoc -v "$^I"
$INPLACE_EDIT
$^I The current value of the inplace-edit extension. Use "undef" to
disable inplace editing.
Mnemonic: value of -i switch.
现在,如果我们重新访问第一部分,添加一个额外的-e,然后添加Deparse,则解释-i开关
$ perl -pie -e " s/abc/cba/g " NUL
Can't do inplace edit: NUL is not a regular file.
$ perl -MO=Deparse -pie -e " s/abc/cba/g " NUL
BEGIN { $^I = "e"; }
LINE: while (defined($_ = <ARGV>)) {
s/abc/cba/g;
}
continue {
die "-p destination: $!\n" unless print $_;
}
-e syntax OK
真的可以将e -pie视为扩展吗?我想是的
$ perl -MO=Deparse -pilogicus -e " s/abc/cba/g " NUL
BEGIN { $^I = "logicus"; }
LINE: while (defined($_ = <ARGV>)) {
s/abc/cba/g;
}
continue {
die "-p destination: $!\n" unless print $_;
}
-e syntax OK
当有疑问时,Deparse或Deparse,-p