in reply to Re: Perl code to format the text file by inserting tag in blank line
in thread Perl code to format the text file by inserting tag in blank line

I tried a perl one liner sepertaely on the output xml file as below:

perl -i -lpe "s/^\s*$/<r><\/r>/g" test(filename i used to check separa +tely)
But when i write this one liner in the main code as below, its not giving any output..(No xml output file is getting generated)
print OUTFILE "$result{$moid}{$ext}{$kpi[$jk]}\n"; perl -i -lpe "s/^\s*$/<r><\/r>/g" $OUTFILE
Could you pl. help on this.

Replies are listed 'Best First'.
Re^3: Perl code to format the text file by inserting tag in blank line
by AnomalousMonk (Archbishop) on Feb 12, 2020 at 08:30 UTC
    print OUTFILE "$result{$moid}{$ext}{$kpi[$jk]}\n"; perl -i -lpe "s/^\s*$/<r><\/r>/g" $OUTFILE

    Command-line syntax cannot be included directly in Perl code. I'm surprised this would even compile!

    Be that as it may, you seem to be trying to check if the string  "$result{$moid}{$ext}{$kpi[$jk]}\n" is a blank line and output  "<r></r>\n" if it is. Try (untested):

    my $out = "$result{$moid}{$ext}{$kpi[$jk]}\n"; $out =~ s{ \A \s* \z }{<r></r>\n}xms; print OUTFILE $out;
    instead.


    Give a man a fish:  <%-{-{-{-<

      Thanks a ton!! it worked.I am a perl beginner and iam still trying hard to code better in PERL. Would you mind explaining the 3 lines of code that you have replied me with?

        Would you mind explaining the 3 lines of code that you have replied me with?

        Note: In addition to the regex doc perlre linked by GrandFather, I would also recommend the excellent perlretut tutorial and the perlrequick quick reference.

        As mentioned before, in your posted code you seem to be trying to fix up some data after you've written it to a file. This is possible, but very tricky; the time to fix your data is before output.

        perl -i -lpe "s/^\s*$/<r><\/r>/g" some_file_name does the trick from the command line, but what is it really doing and how can you incorporate it in your Perl code? Deparsing can be helpful; see the O and B::Deparse core modules:

        c:\@Work\Perl\monks>perl -MO=Deparse,-p -i -lpe "s/^\s*$/<r><\/r>/g" BEGIN { $^I = ""; } BEGIN { $/ = "\n"; $\ = "\n"; } LINE: while (defined(($_ = <ARGV>))) { chomp($_); s[^\s*$][<r></r>]g; } continue { print($_); } -e syntax OK
        This is the internal code generated and executed with the  -i -l -p command-line switches (see perlrun). The workhorse  s/// has been enclosed in a loop. The  s[^\s*$][<r></r>]g expression operates by default on the  $_ default scalar (see perlop and perlvar), which you can see being assigned values, successive records/lines from a file, in the while-loop condition expression in the deparsed code. (Note that the  /g substitution modifier is not needed here (although it does no harm): the entire line is being replaced and this can only be done once.)

        But you want to fix up the data before output. The first step is to generate the data:
            my $out = "$result{$moid}{$ext}{$kpi[$jk]}\n";
        Then check the data and fix it if necessary:
            $out =~ s{ \A \s* \z }{<r></r>\n}xms;
        Here,  s/// operates not on  $_ but on the  $out variable; this is accomplished by the  =~ "binding" operator (see perlop).
        Finally, output correct data:
            print OUTFILE $out;

        The  $out =~ s{ \A \s* \z }{<r></r>\n}xms; fixup statement could have been written in other, perhaps better ways. For instance:
            $out = "<r></r>\n" if $out =~ m{ \A \s* \z }xms;
        which might be narrated as "$out is changed to an empty <r>-pair if $out matches a blank line." (Note the  m// operator is used here, not substitution; see perlop.) This is perhaps clearer and thus more easily maintainable than doing the same thing with substitution. Developing this a bit further, one might write something like

        use constant BLANK_LINE => qr{ \A \s* \z }xms; use constant EMPTY_R_PAIR => "<r></r>\n"; ... $out = EMPTY_R_PAIR if $out =~ BLANK_LINE;
        which could be considered self-documenting and moreover allows easy global alteration of the meanings of BLANK_LINE and EMPTY_R_PAIR. (This is an example of the Don't Repeat Yourself (DRY) or "define in one place" principle.)

        And that's all there is to it. It's a Simple Matter of Programming. :)


        Give a man a fish:  <%-{-{-{-<

        Minor aside: the language is Perl, not PERL. It isn't an acronym for anything, although there are plenty of bacronyms - "Pathologically Eclectic Rubbish Collector" is one of my favourites.

        See the Perl documentation for regular expression help. A good place to start is perlre.

        Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond