May i ask a question about reading file?

while(0){ print 'hi' }

Will never print hi.

cat 1.txt:
0

open FH, '1.txt' or die;
while(<FH>) { print 'hi' }

This will print hi.

Since $_ == 0 here, why while become true?

I am confused about this.

Regards 

November 20, 2022, 8:57 PM, "Kang-min Liu" <gu...@gugod.org> wrote:


> 
> linux...@gmx.net writes:
> 
> > 
> > I have a large file which has millions of lines.
> >  They are text only lines.
> >  If I have to change one line in the file, what's the efficient way?
> >  I don't want to slurp the whole file into memory, change that line and
> >  write the full content back to disk again.
> > 
> 
> It seems like the editing is line-based, I could recommend checking out
> 'perl -i' for doing in-place editing, if you are OK with regexp-based
> search & replace -- it's basically the same as doing it in vim,
> 
>  perl -p -i.orig -e "s/hello/wow/" input.txt
> 
> This finds the first line that matces regexp ^foo$ , then replaces the
> entire line with "foobar", shift the remainder of the file correctly and
> wrote everything back to input.txt -- while keep an original copy of 
> input.txt at
> input.txt.orig
> 
> However that may match on multiple lines, if you know the line number in
> advance, you could check the line number variable $.
> 
>  perl -p -i -e "s/^.+$/wow/ if $. == 2" input.txt
> 
> Note that doing this would still scan the entire input.txt line by
> line. And adding `exit()` or `next` in the body of `-e` would make the
> program finish early but would also truncate input.txt -- which is
> probblay not what we want.
> 
> ----
> 
> Alternatively, if you are looking for doing this with some code but not
> with "perl" command, read on...
> 
> How efficient it could be depends a little bit on how the target line is
> identified and the kind of editing that's required.
> 
> For sure you could avoid slupring by doing doing line-based changes
> like:
> 
>  while (defined(my $line = <$fh>)) {
>  ...
>  }
> 
> If the editing is replacing $line with something that's equal in length,
> then it can be pretty efficient -- just print the thing and the file is
> modified in place.
> 
> If, say, we want to just just the 42nd line in the file, here's how I
> would do:
> 
>  # Open as read-write mode.
>  open my $fh, "+<", "input.txt";
> 
>  # Seek to the beginning of 42nd line
>  my $lineno = 1;
>  while (defined(my $line = <$fh>)) {
>  $lineno += 1;
>  last if $lineno == 42;
>  }
> 
>  # Print the new content at the begging of 42nd line.
>  print $fh $newcontent;
> 
> This is the most efficient scenario because the program can end here
> without reading the remainder of input.txt.
> 
> However, if $newcontent is longer than the 42nd line, the program would
> still finish and when we inspect the file, we'll see that the text in
> $newcontext bleed over to the 43rd line and maybe further lines.
> 
> Similarly, if the $newcontent is shorter, the original conten in the
> 42nd line will only be partially replaced.
> 
> Most likely that's not the kind of editing we want to be doing.
> 
> Meaninng, if $newcontent is longer or shorter, the remainder of the file
> should be shifted a few characters forward or backword and we want to
> re-print those lines back to $fh -- which also requires a lot of bookkeeping
> code just to get everything corner case right.
> 
> If the editing we want is rather generic I'd say we probably want to put
> the output to a different file instead of doing in-place editing.
> 
> And we will still end up slurping the entire file, but only keeping one
> line at a time in memory.
> 
> --
> Cheers,
> Kang-min Liu
> 
> -- 
> To unsubscribe, e-mail: beginners-unsubscr...@perl.org
> For additional commands, e-mail: beginners-h...@perl.org
> http://learn.perl.org/
>

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to