Reputation: 1032
In Perl one liner, we can use the -i
argument to do an in-place substitution. What's the equivalence of -i
when writing perl code in the IDE?
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..
Thanks in advance.
Upvotes: 3
Views: 335
Reputation: 40718
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.
The $^I
and ARGV
variables are decribed in perlvar
See perlop for information about why you should use <<>>
instead of <>
.
while(<>) { ... }
According to perlop, the loopwhile (<>) { ... # code for each line }
is equivalent to the following Perl-like pseudo code:
unshift(@ARGV, '-') unless @ARGV; while ($ARGV = shift) { open(ARGV, $ARGV); while (<ARGV>) { ... # code for each line } }
$^I=""
:According to 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.
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; 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.
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;
Upvotes: 2