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

Hi, and thanks for reading!

This seems like it should be pretty simple to figure out, but I guess don't know enough Perl yet to make it work. I need to find a multi-line string in a text file, delete it, and delete the blank line above it. I'm able to delete the string itself, but not the blank line above it.

The file is structured as follows:

start_of_block { some_data ; more_data ; even_more ; }; start_of_block { data ; };

Here's what I tried:

$/ = "" ; while (<>) { s/\nstart_of_block.*?};//s print ; }

If I remove the \n from the beginning of the pattern, the block is deleted, but of course the newline remains. With the \n in place, the match simply fails.

Any pointers?

Replies are listed 'Best First'.
Re: delete above matching line?
by moritz (Cardinal) on Jul 01, 2010 at 07:22 UTC

    Your while-loop reads line by line, so you can never match the previous line in a regex.

    I gets much easier if you read the whole file into a string, and then apply a substitution.

    I don't know what output you expect, but this might do you want:

    s/^\s*start_of_block\s*\{.*?\};\s*//xmsg;

    If not, please tell us exactly what output you want.

    Perl 6 - links to (nearly) everything that is Perl 6.

      Reading the file into a string did the trick, thanks.

      { local $/ = undef ; open TEST,'test' or die "Denied: $!\n" ; my $string = <TEST> ; close TEST ; $string =~ s/\n\nstart_of_block.*?};//s ; print $string ; }
        For bigger files:
        my @out; my $print = 1; while (<>) { if (m/^start_of_block/) { $print = 0; pop @out if @out and $out[-1] eq $/; # removes previous empty line } push @out, $_ if $print; if (m/^};/) { $print = 1; } print shift @out if $print and 1 < @out; } # UPDATE: based on oldmanwillow reply: # print @out; print @out if $out[-1] =~ /^\s*$/ ;
Re: delete above matching line?
by Utilitarian (Vicar) on Jul 01, 2010 at 08:54 UTC
    Hi,

    The following is a rough spec for what I understand to be your issue.

    While processing through the file, if this line doesn't match, print the previous line and store this line as the previous line.

    However if this line matches don't print the previous line and set the previous line string to "".

    By the way, Do you want to keep the closing braces?

    print "Good ",qw(night morning afternoon evening)[(localtime)[2]/6]," fellow monks."
      Yep, that's pretty much it. The closing braces should be deleted.