Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Perl code to format the text file by inserting tag in blank line

by DAN0207 (Acolyte)
on Feb 12, 2020 at 05:08 UTC ( [id://11112830]=perlquestion: print w/replies, xml ) Need Help??

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

I have a input file with contents as below:

<mt>llbreserve_Stov1</mt> <mt>llbreserve_Stov2</mt> <mt>preserve_Stov1</mt> <mt>qreserve_Stov1</mt> <mt>qreserve_Stov2</mt> <mt>mnreserve_Stov1</mt> <mt>slmreserve_Stov1</mt> <mt>slmreserve_Stov2</mt> <mt>envreserve_Stov1</mt> <mt>envreserve_Stov2</mt> <mv> <value>MT=DUOSQ2,Eb=43789,Fc=67890</value> <r>0</r> <r>0</r> <r>0</r> <r>0</r> <r>0</r> <r>0</r> <r>0</r> <r>0</r> <r>0</r> <r>0</r> </mv>

I have written the code(pasting here only the specific code,not all lines)as below:

# Writing output from mt step until mv for reserve meas only $dimens=scalar(keys(%ind)); for ($jj=1; $jj <= $dimens; $jj++) { # Writing output mt reserve meas list print OUTFILE "<mt>$kpi[$jj]<\/mt>\n"; } foreach $value (keys %result) { foreach $ext (keys %{$result{$value}}) { print OUTFILE "<mv>\n"; print OUTFILE "$value".",resv="."$ext<\/va +lue>\n"; for ($jk=1; $jk <= $dimens; $jk++) { # Writing output r meas list result so +rted in the same order than mt list print OUTFILE "$result{$value}{$ext}{$ +kpi[$jk]}\n"; } print OUTFILE "<\/mv>\n"; } } print OUTFILE "$line\n";

The output file which i get after executing the code is

<mt>llbreserve</mt> <mt>preserve</mt> <mt>qreserve</mt> <mt>mnreserve</mt> <mt>slmreserve</mt> <mt>envreserve</mt> <mv> <value>MT=DUOSQ2,Eb=43789,Fc=67890,resv=Stov1</value> <r>0</r> <r>0</r> <r>0</r> <r>0</r> <r>0</r> <r>0</r> </mv> <mv> <value>MT=DUOSQ2,Eb=43789,Fc=67890,resv=Stov2</value> <r>0</r> <r>0</r> <r>0</r> <r>0</r>

I can see that there are some blank lines where the combination is not present(Stov1 is present for all meas whereas Stov2 is not present for all.)I am planning to insert a tag like <r></r> in place of blank lines so that further processing of my outputfile is valid. Could you pl. help me to achieve this.TIA

Replies are listed 'Best First'.
Re: Perl code to format the text file by inserting tag in blank line
by GrandFather (Saint) on Feb 12, 2020 at 05:37 UTC

    The sample data you give looks like a fragment of XML. If that is the case it is strongly advised that you use a suitable module (XML::Twig, XML::LibXML, ...) to do the heavy lifting for you.

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

      Yes it is XML file format.and it is required to use only PERL code

        Yes, even you can use CPAN

        You may like to explain why you can't use cpan modules if that is indeed the case.

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

        By "it is required to use only PERL code", do you mean that you may not use Perl modules such as the ones suggested by GrandFather?


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

        There's Perl (the language) and perl (the "interpreter"). There is no PERL.

        Jenda
        1984 was supposed to be a warning,
        not a manual!

Re: Perl code to format the text file by inserting tag in blank line
by haukex (Archbishop) on Feb 12, 2020 at 10:27 UTC

    You should definitely use an appropriate module for this - see Parsing HTML/XML with Regular Expressions for why. You said here that you have security restrictions, and I fully agree with afoken that not using the appropriate modules and instead reinventing the wheel makes it more likely that your code will be a security risk; you should speak to your managers about that. And you may already have the appropriate libraries installed anyway: XML::LibXML is based on libxml2, and XML::Parser (used in e.g. XML::Twig) is based on libexpat.

Re: Perl code to format the text file by inserting tag in blank line
by AnomalousMonk (Archbishop) on Feb 12, 2020 at 06:26 UTC
    $dimens=scalar(keys(%ind)); for ($jj=1; $jj <= $dimens; $jj++) { # Writing output mt reserve meas list print OUTFILE "<mt>$kpi[$jj]<\/mt>\n"; } ... ... for ($jk=1; $jk <= $dimens; $jk++) { # Writing output r meas list result sorted in the same ord +er than mt list print OUTFILE "$result{$value}{$ext}{$kpi[$jk]}\n"; } ... ... ...

    Just something that caught my eye... I don't know how you are initializing the  @kpi array, but with this code, it needs one more element than the number of elements in the  %ind hash (Perl arrays are 0-based by default).


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

      I think the OP is probably ok here.
      He is using arrays in a "non-Perl" way and with explicit indices starting at 1 instead of 0. Not using array[0] is allowed. $kpi[0] is probably undef.

      "Off by one" is one of the most common errors in programming. I personally would rewrite the code so that it doesn't use indices at all like: foreach my $element (@array){} However a re-write like appears to be outside the scope of the question before us. Perl code like that would use index 0. However there would not be any direct reference to that zero index within the code at all. Creating the kpi array would use "push" instead of explicit indices from 1..n. If the OP creates the kpi array with starting with $kpi[1] that just makes index 0 undef (skips it). I don't see any indication that the OP is aware of: push,pop,shift,unshift.

        I think the OP is probably ok here.

        I'm not so sure. DAN0207 is a self-described Perl "beginner", and looking at other posts by this monk doesn't give me the sense that he or she is necessarily aware of the issue of 0- versus 1-based arrays. We also cannot see anything about how the  @kpi array is initialized. The whole thing made my buggy-sense tingle.

        However, DAN0207 hasn't seen the need to follow up on the point I made here (indeed, replying with a question on a completely different topic), so I guess everything's ok...


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

      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.
        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:  <%-{-{-{-<

A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2024-04-18 01:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found