【发布时间】:2011-10-30 13:38:27
【问题描述】:
这行得通:
perl -pi -e 's/abc/cba/g' hellofile
但这不是:
perl -pie 's/cba/abc/g' hellofile
换句话说 -pi -e 有效,但 -pie 无效。为什么?
【问题讨论】:
标签: perl
这行得通:
perl -pi -e 's/abc/cba/g' hellofile
但这不是:
perl -pie 's/cba/abc/g' hellofile
换句话说 -pi -e 有效,但 -pie 无效。为什么?
【问题讨论】:
标签: perl
-i 标志采用一个可选参数(如果存在,必须紧跟在它之后,而不是在单独的命令行参数中),该参数指定附加到输入文件名称的后缀,以便创建备份。写入perl -pie 's/cba/abc/g' hellofile 会导致e 被视为此后缀,并且由于e 不会被解释为正常的-e 选项,Perl 会尝试运行位于s/cba/abc/g 中的脚本,这可能不会不存在。
【讨论】:
因为-i 为备份文件采用可选扩展名,例如-i.bak,因此其他标志不能直接跟在 -i 之后。
-i[扩展名]
指定要编辑由 构造处理的文件 到位。它通过重命名输入文件,打开输出来做到这一点 文件,并选择该输出文件作为 print() 语句的默认值。扩展名(如果提供)用于 按照这些修改旧文件的名称以制作备份副本 规则:
如果没有提供扩展名,则不进行备份并且当前文件是 覆盖。
如果扩展名不包含 * ,则将其附加到末尾 当前文件名的后缀。如果扩展名确实包含一个 或多个 * 字符,然后将每个 * 替换为当前 文件名。在 Perl 术语中,您可以将其视为:
【讨论】:
perl 已经告诉你原因了 :) Try-It-To-See
$ 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 in -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
【讨论】: