这有效:
perl -pi -e 's/abc/cba/g' hellofile
Run Code Online (Sandbox Code Playgroud)
但这不是:
perl -pie 's/cba/abc/g' hellofile
Run Code Online (Sandbox Code Playgroud)
换句话说-pi -e工作,但-pie不工作.为什么?
jwo*_*der 15
该-i标志采用可选参数(如果存在,则必须紧跟在其之后,而不是在单独的命令行参数中),该参数指定为了创建备份而附加到输入文件名称的后缀.写入perl -pie 's/cba/abc/g' hellofile会导致将e其视为此后缀,并且由于e不会将其解释为正常-e选项,因此Perl会尝试运行位于s/cba/abc/g其中的脚本,该脚本可能不存在.
因为-i备份文件的可选扩展名,例如-i.bak,因此其他标志不能直接跟随-i.
-i [延伸]
指定由<>构造处理的文件将被就地编辑.它通过重命名输入文件,按原始名称打开输出文件,并选择该输出文件作为print()语句的默认值来完成此操作.扩展(如果提供)用于修改旧文件的名称以制作备份副本,遵循以下规则:
如果未提供扩展,则不进行备份,并覆盖当前文件.
如果扩展名不包含*,则将其作为后缀附加到当前文件名的末尾.如果扩展名包含一个或多个*字符,则每个*将替换为当前文件名.在Perl术语中,您可以将其视为:
Perl中已经告诉你为什么:) 牛逼 ry- 我叔牛逼邻小号 EE
$ perl -pie " s/abc/cba/g " NUL
Can't open perl script " s/abc/cba/g ": No such file or directory
Run Code Online (Sandbox Code Playgroud)
如果您使用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
Run Code Online (Sandbox Code Playgroud)
如果你在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.
Run Code Online (Sandbox Code Playgroud)
现在,如果我们重新访问第一部分,添加一个额外的-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
Run Code Online (Sandbox Code Playgroud)
真的可以将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
Run Code Online (Sandbox Code Playgroud)
当有疑问时,Deparse或Deparse,-p