Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Delete last line of file with regex

by nysus (Vicar)
on Jul 22, 2020 at 17:34 UTC ( #11119669=perlquestion: print w/replies, xml ) Need Help??

nysus has asked for the wisdom of the Perl Monks concerning the following question:

I want to delete the last line of a file but only if it begins with ##

#!/usr/bin/env perl my $slurp; while (<DATA>) { $slurp .= $_; } $slurp =~ s/^###* [^\n]+//m; print $slurp; __DATA__ kjkjksjdf ## Don't del me blah ## deleteme

I don't know how to indicate that nothing should come after the line or how to indicate EOF in a regex.

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: Delete last line of file with regex
by choroba (Archbishop) on Jul 22, 2020 at 18:33 UTC
    Do you really need to detect the eof from inside the regex?
    while (<>) { print unless /^##/ && eof; }
    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: Delete last line of file with regex
by tybalt89 (Prior) on Jul 22, 2020 at 17:41 UTC
    #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11119669 use warnings; my $slurp; while (<DATA>) { $slurp .= $_; } $slurp =~ s/^##.*\n\z//m; print $slurp; __DATA__ kjkjksjdf ## Don't del me blah ## deleteme
Re: Delete last line of file with regex
by jwkrahn (Monsignor) on Jul 22, 2020 at 22:13 UTC
    I want to delete the last line of a file but only if it begins with ##
    #!/usr/bin/env perl my $slurp; while (<DATA>) { $slurp .= $_; }
    my $slurp; while (<DATA>) { last if eof && /^###* /; $slurp .= $_; }
Re: Delete last line of file with regex
by ForgotPasswordAgain (Priest) on Jul 23, 2020 at 01:38 UTC

    If it's not a huge file, I'd use File::Slurp (or maybe File::Slurper if the issues it fixes are relevant for your case).

    @lines = read_file($file); pop @lines if $lines[-1] =~ /^##/; write_file($file, @lines);
Re: Delete last line of file with regex
by dsheroh (Monsignor) on Jul 23, 2020 at 08:02 UTC
    Another variation on the "don't add the line to your string in the first place" concept, rather than using eof, would be to read the lines into an array instead of a scalar, remove the last entry from the array if it matches the regex, and then join the (remaining) lines into a single string:
    my @lines = <DATA>; if ($lines[-1] =~ /^##/) { pop @lines; } my $slurp = join '', @lines;
      my @lines = <DATA>; if ($lines[-1] =~ /^##/) { pop @lines; } my $slurp = join '', @lines;

      Note that this will keep the entire file twice in memory (except for the very last line if it starts with ##). That's ok if you have only small files or large amounts of memory. But for large files and limited memory, this may get you into an out-of-memory situation.

      See also perlfaq3 and perlfaq5.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
        In that case you could seek to a position close to the end-of-file, walk backward until you find a newline, use a regex to see if the last line matches, and if so, remove it. Then, truncate the file at the current position and append the modified string to it. This would work on a file of any size while using a minimal amount of memory.
Re: Delete last line of file with regex
by perlfan (Vicar) on Jul 23, 2020 at 02:25 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://11119669]
Approved by haukex
Front-paged by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2020-11-26 19:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?