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

hi,

would like to seek your advise for easiest way to alter a file using perl.

say i have below lines in a file:

A ZZZ YYY XXX B A B A FFF SSS GGG B A B A WWW EEE TTT B

My objective is to remove lines A & B if there is nothing in between them.

thanks much!...

Replies are listed 'Best First'.
Re: file alteration
by choroba (Cardinal) on Apr 14, 2015 at 06:31 UTC
    Use the input record separator:
    local $/ = "A\nB\n"; chomp, print while <>;

    Just make sure your files end in a newline, otherwise the last "A\nB" at the EOF won't be removed.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: file alteration
by davido (Cardinal) on Apr 14, 2015 at 04:58 UTC
    perl -00pi.~* -e 's/A\nB\n//g' testfile

    Dave

Re: file alteration
by GrandFather (Saint) on Apr 14, 2015 at 03:54 UTC

    Hi, I would like to see what you have tried.

    Perl is the programming world's equivalent of English
      A = <tr> B = </tr> perl -00pi.~* -e 's/\<tr\>\n\<\/tr\>\n//g' $file
      it does not do anything.

        No idea what all those backslashes are doing in there.

        $ cat file x <tr> </tr> y <tr> </tr> z $ perl -00pi.~ -e 's/<tr>\n<\/tr>\n//g' file $ cat file x y z

        I can understand where you might feel that you're saving everyone's time and simplifying the problem's explanation by using A and B as stand-ins for more complex constructs, but the truth is that you would have saved your time, and the time of those who contributed answers had you simply told us from the start that A and B represented <tr> tags. Then we could have suggested an appropriate solution from the start, rather than getting around to it eventually after all the facts emerged.

        And in my opinion, kudos to jeffa for the most appropriate solution for handling HTML.


        Dave

Re: file alteration
by jeffa (Bishop) on Apr 14, 2015 at 17:14 UTC

    While we always appreciate someone taking the time to present an easy to digest model of their problem domain, in this case the devil is in the details. And that is you really have data that is HTML. A good rule of thumb is to not parse and alter HTML with regular expressions. Doesn't mean you can't and it does not mean you should not ... it just means that if you take the time now to provide a more proper solution, you will more than likely save yourself and others time and pain down the road. Having said that ... pretty much everything that renders HTML these days will ignore empty <tr> groupings for you. Are you sure you really need to do anything at all?

    UPDATE: wouldn't this be a more robust solution for your needs? (moved my example data to code block below)

    use strict; use warnings; use XML::Twig; my $twig = XML::Twig->new( twig_handlers => { tr => \&prune_tr }, pretty_print => 'indented', ); $twig->parse( \*DATA ); $twig->print; sub prune_tr { my ($handler, $tr) = @_; $tr->delete unless $tr->children; } __DATA__ <table> <tr> <td>ZZZ</td> <td>YYY</td> <td>XXX</td> </tr> <tr> </tr> <tr> <td>FFF</td> <td>SSS</td> <td>GGG</td> </tr> <tr> </tr> <tr> <td>WWW</td> <td>EEE</td> <td>TTT</td> </tr> </table>

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: file alteration
by crusty_collins (Friar) on Apr 14, 2015 at 13:58 UTC
    This works for me

    use strict; use warnings; use Data::Dumper; foreach my $line (<DATA>) { chomp($line); $line =~ s/^A$|^B$//; if ( $line ) { print "$line\n"; } } __DATA__ A ZZZ YYY XXX B A B A FFF SSS GGG B A B A WWW EEE TTT BCC
Re: file alteration
by FreeBeerReekingMonk (Deacon) on Apr 14, 2015 at 17:50 UTC