我想知道Perl在使用选项perl -pi -e
执行时运行的等效代码是什么?
在某些问题上我可以读到这个:
while (<>) {
... # your script goes here
} continue {
print;
}
但是此示例未显示保存文件的部分。
Perl如何确定EOL?没有发生任何变化时是否触摸文件?例如,如果我有一个旧的MAC文件(仅\r
)。它如何处理s/^foo/bar/gm
?
我尝试使用Perl调试器但它并没有真正帮助。所以我只想猜测:
#!/usr/bin/env perl
my $pattern = shift;
map &process, @ARGV;
# perl -pi -e PATTERN <files>...
sub process {
next unless -f;
open my $fh, '<', $_;
my $extract;
read $fh, $extract, 1024;
seek &fh, 0, 0;
if ($extract =~ /\r\n/) {
$/ = "\r\n";
} elsif ($extract =~ /\r[^\n]/) {
$/ = "\r";
} else {
$/ = "\n";
}
my $out = '';
while(<&fh>) {
my $__ = $_;
eval $pattern;
my $changes = 1 if $_ ne $__;
$out .= $_;
}
if($changes)
{
open my $fh, '>', $_;
print $fh $out;
}
close &fh;
}
答案 0 :(得分:8)
您可以使用核心模块B :: Deparse检查Perl实际使用的代码。使用选项-MO=Deparse
激活此编译器后端模块。
$ perl -MO=Deparse -p -i -e 's/X/U/' ./*.txt
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
s/X/U/;
}
continue {
die "-p destination: $!\n" unless print $_;
}
-e syntax OK
因此perl循环遍历给定文件中的行,执行代码并将$ _设置为行并打印结果$ _。
魔法变量$ ^ I被设置为空字符串。这将在现场编辑。就地编辑在perldoc perlrun中进行了解释。没有检查文件是否未更改。因此,始终更新编辑文件的修改时间。显然,备份文件的修改时间与原始文件的修改时间相同。
使用-0标志可以设置输入记录分隔符,以便为Mac文件使用“\ _”。
$ perl -e "print qq{aa\raa\raa}" > t.txt
$perl -015 -p -i.ori -e 's/a/b/' t.txt
$cat t.txt
ba
$ perl -MO=Deparse -015 -p -i.ori -e 's/a/b/'.txt
BEGIN { $^I = ".ori"; }
BEGIN { $/ = "\r"; $\ = undef; }
LINE: while (defined($_ = <ARGV>)) {
s/a/b/;
}
continue {
die "-p destination: $!\n" unless print $_;
}
-e syntax OK
答案 1 :(得分:0)
-p assumes an input loop around your script. Lines are printed.
-i files processed by the < > construct are to be edited in place.
-e may be used to enter a single line of script. Multiple -e commands may be given to build up a multiline script.