Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: Remove Blank Lines Off the End of a File

by dragonchild (Archbishop)
on Feb 27, 2002 at 20:54 UTC ( [id://148035]=note: print w/replies, xml ) Need Help??


in reply to Remove Blank Lines Off the End of a File

Don't use Perl if you don't want to read the whole file in. Use some manner of shell scripting or C. (In C, the function you're looking for is seek(), similar to the Perl seek.)

------
We are the carpenters and bricklayers of the Information Age.

Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Replies are listed 'Best First'.
Re: Re: Remove Blank Lines Off the End of a File
by PrakashK (Pilgrim) on Feb 27, 2002 at 21:06 UTC
    Don't use Perl if you don't want to read the whole file in
    Sure you can do this in perl without reading the whole file. Here's some code (untested) (updated to fix a couple of mistakes).
    #!/usr/bin/perl -w use strict; my $file = shift or die; open my $fh, "+<$file" or die "$!"; my $size = 4096; my ($cur_pos, $buf); seek $fh, -$size, 2; while (1) { $cur_pos = tell $fh; read $fh, $buf, $size; last if $buf =~ m/\S/s; seek $fh, -$size, 1; } $buf =~ m/(\s+)$/s; $cur_pos += $-[0]; truncate $fh, $cur_pos; close $fh; exit 0;
    This will read only what is necessary and does not keep what it has already processed.

    I am sure there are better ways of doing this.

    /prakash

    Update: I finally got some time and tested the above and found another bug (fixed in the code above). I was not supposed to use sysread and seek<code> together (<code>sysseek will probably do fine), so I changed the sysread to <code>read<code>, and it worked ok.

    (Note to self: Never post untested code.)


      Very nice.

      However, it strips the last \n from the file (which probably isn't desirable) and it truncates non-whitespace data if there isn't a final \n. Which means that if you run the program twice in a row it will strip non-whitespace data from the end of the file.

      Also, your tell() is followed by a read() so the next seek() starts from the EOF again and not from $cur_pos. ;-)

      The following changes fix these problems:

      #!/usr/bin/perl -w use strict; my $file = shift or die; open my $fh, "+<$file" or die "$!"; binmode $fh; # Just in case my $size = 4096; my ($cur_pos, $buf); seek $fh, -$size, 2; while (1) { $cur_pos = tell $fh; read $fh, $buf, $size; last if $buf =~ m/\S/s; seek $fh, -$size*2, 1; } $buf =~ m/(\s+)$/s; $cur_pos += $-[0] || 0; truncate $fh, ++$cur_pos if $cur_pos; close $fh; exit 0;

      --
      John.

      This works! Thanks Prakash!

      -biz-

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://148035]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2024-03-29 06:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found