在Perl衬里中,我们可以使用-i
参数进行就地替换。在IDE中编写Perl代码时,-i
的等效功能是什么?
考虑以下代码:
binmode(STDOUT, ':raw');
open my $fh, '<', $filename;
while (<$fh>) {
s/^/<rootroot>/ if $.==1;
if (/(<link rel[^<>\n]*?)(\/?)(>)/g) {
my ($p1, $p2, $p3) = ($1, $2, $3);
s/$p1$p2$p3/($p2 ? qq|$p1$p2$p3<span class="entry">| : qq|$p1\/$p3<span class="entry">|)/ge;
};
s/<\/>/<entry_end><\/entry_end>/;
s/$/<\/rootroot>/ if eof;
}
如何将所有更改行保存到位?
因为我需要在就地更改html源代码后立即使用XML :: LibXML对html文件进行快速验证。
先谢谢了。
答案 0 :(得分:2)
您可以尝试以下操作:
my $filename = 'test.dat';
@ARGV = ($filename);
$^I = '';
while(<<>>) {
binmode(ARGV, ':raw');
# Do the substitiution on $_ here ...
print;
}
我没有找到如何在循环之前设置binmode
的方法,因为ARGV
仅在使用<>
运算符之后才定义。
while(<>) { ... }
根据{{3}},循环while (<>) { ... # code for each line }
等效于以下类似Perl的伪代码:
unshift(@ARGV, '-') unless @ARGV; while ($ARGV = shift) { open(ARGV, $ARGV); while (<ARGV>) { ... # code for each line } }
$^I=""
:根据perlop:
如果未提供扩展名,并且您的系统支持,则原始 输出重定向到文件时,文件保持打开状态且没有名称 具有原始文件名的新文件。无论Perl是否干净地退出, 原始文件已取消链接。
以及perlrun博客中的更多信息:
Perl打开并立即取消链接原始文件,然后打开一个 具有相同名称的新文件(新文件描述符和索引节点),并发送 输出到第二个文件;最后,关闭旧文件, 由于已取消链接而被删除,剩下的就是更改 与原始文件同名的文件。
有关实际实现,另请参见this。
根据上述情况,可能会发生以下情况:
my $fn = 'test.dat';
open ( my $fh, '<:raw', $fn ) or die "Could not open file '$fn': $!";
unlink $fn or die "$!";
open ( my $fh2, '>:raw', $fn ) or die "Could not reopen file '$fn': $!";
while(<$fh>) {
# Do the substitutions on $_ here ...
print $fh2 $_;
}
close $fh;
close $fh2;