[英]Perl in-place substitution
In Perl one liner, we can use the -i
argument to do an in-place substitution. 在Perl one liner中,我们可以使用
-i
参数进行就地替换。 What's the equivalence of -i
when writing perl code in the IDE? 在IDE中编写perl代码时
-i
的等价性是什么?
Consider the following code: 请考虑以下代码:
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;
}
How can we save all the lines of changes in-place? 我们如何才能保存所有变更线?
Because I need to do a quick validation on the html file using XML::LibXML right after the in-place change of the html source.. 因为我需要在html源的就地更改后立即使用XML :: LibXML对html文件进行快速验证。
Thanks in advance. 提前致谢。
You can try something like this: 你可以尝试这样的事情:
my $filename = 'test.dat';
@ARGV = ($filename);
$^I = '';
while(<<>>) {
binmode(ARGV, ':raw');
# Do the substitiution on $_ here ...
print;
}
I did not find out how to set binmode
before the loop, since ARGV
is only defined after the <>
operator has been used. 我没有找到如何在循环之前设置
binmode
,因为ARGV
仅在使用<>
运算符之后定义。
The $^I
and ARGV
variables are decribed in perlvar
$^I
和ARGV
变量在perlvar
See perlop for information about why you should use <<>>
instead of <>
. 有关为什么应该使用
<<>>
而不是<>
信息,请参阅perlop 。
while (<>) { ... # code for each line }
is equivalent to the following Perl-like pseudo code:
等效于以下类似Perl的伪代码:
unshift(@ARGV, '-') unless @ARGV; while ($ARGV = shift) { open(ARGV, $ARGV); while (<ARGV>) { ... # code for each line } }
$^I=""
: $^I=""
: According to perlrun : 根据perlrun :
If no extension is supplied, and your system supports it, the original file is kept open without a name while the output is redirected to a new file with the original filename.
如果没有提供扩展,并且您的系统支持它,则原始文件将保持打开状态而没有名称,而输出将重定向到具有原始文件名的新文件。 When perl exits, cleanly or not, the original file is unlinked.
当perl退出时,干净利落或不干净,原始文件被取消链接。
and some more information in this blog: 以及此博客中的更多信息:
Perl opens and immediately unlink()s the original file, then opens a new file with the same name (new file descriptor and inode), and sends output to this second file;
Perl打开并立即取消链接()原始文件,然后打开一个具有相同名称的新文件(新文件描述符和inode),并将输出发送到第二个文件; at the end, the old file is closed and thus deleted because it was unlinked, and what's left is a changed file with the same name as the original.
最后,旧文件被关闭,因此被删除,因为它是未链接的,剩下的是一个与原始文件同名的更改文件。
See also doio.c for actual implementation. 有关实际实现,另请参见doio.c.
According to the above, the following might work: 根据以上所述,以下可能有效:
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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.