Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

How to add a new line after three or four lines from a pattern after getting that pattern

by anirbanphys (Beadle)
on Apr 03, 2019 at 10:06 UTC ( #1232072=perlquestion: print w/replies, xml ) Need Help??

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

Hello Monks,

My intention is to print a new line "default_operating_conditions : " in a new file. The given code is able to search a pattern "operating_conditions" from the input file (INPUT) and doing some intended operation. The output of the file should be looking like file OUTPUT.

Here my code is printing the intended line just after the matched pattern in the output. I need to print the intended line after four line (5TH LINE) from the pattern.

Can you folks please guide me :).

The perl code is

use strict; use warnings; my $inputfile = $ARGV[0]; # input FILE my $opt_cond; my $iline; if ($#ARGV!=0){ print "USAGE :: perl default_operating_condition_update.pl <<FILE>> + \n\n" ; exit(1); } my $cmd = "mkdir finallib;"; system ($cmd); my @operating_cond; open (INFILE,"<","$inputfile") || die "Can not open Input LIB File"; open (my $OPFILE,">","finallib/$inputfile") || die "Can not open Input + Text File"; while ($iline = <INFILE>) { chomp $iline; print $OPFILE "$iline\n"; if ($iline =~m/^\s*operating_conditions/g) { @operating_cond=split (operating_conditions,$iline); @operating_cond=split ("{",$operating_cond[1]); @operating_cond=split (/\(/,$operating_cond[0]); @operating_cond=split (/\)/,$operating_cond[1]); $opt_cond = $operating_cond[0]; print $OPFILE " default_operating_conditions : $operating_cond[0] +;\n" ; } }

The input file for the code is

library(and_gate) { delay_model : table_lookup ; date : "Fri Mar 15 03:44:39 " ; time_unit : 1ms ; voltage_unit : 1V ; current_unit : 1A ; operating_conditions ("AB0.5v45c") { process : 1 ; temperature : 45 ; voltage : 0.5 ; } input_voltage(default) { vi : 0 ; vh : 0.5 ; vim : 0 ; vin : 0.5 ; } }

The output should be look like

library(and_gate) { delay_model : table_lookup ; date : "Fri Mar 15 03:44:39 " ; time_unit : 1ms ; voltage_unit : 1V ; current_unit : 1A ; operating_conditions ("AB0.5v45c") { process : 1 ; temperature : 45 ; voltage : 0.5 ; } default_operating_conditions : "AB0.5v45c" ; input_voltage(default) { vi : 0 ; vh : 0.5 ; vim : 0 ; vin : 0.5 ; } }
  • Comment on How to add a new line after three or four lines from a pattern after getting that pattern
  • Select or Download Code

Replies are listed 'Best First'.
Re: How to add a new line after three or four lines from a pattern after getting that pattern
by thanos1983 (Parson) on Apr 03, 2019 at 11:00 UTC

    Hello anirbanphys,

    One possible way is:

    Update: I have hard-coded the data but you can do the parsing. My approach is to read the file in an array so you can know the exact position of the line that you want to alter. Next step insert a new line without altering the array using splice.

    Sample of code to split string and insert it:

    Update 2: All the commends together in one solution:

    Update 3: Adding a better (more strict) regex to the solution:

    Hope this helps, BR.

    Seeking for Perl wisdom...on the process of learning...not there...yet!
      Thank you thanos1983 for your help.

      The above mentioned code will be working if we remove the "HARD CODED" "default_operating_conditions : "AB0.5v45c" ;". If you look at my code, I am doing some operations for getting "AB0.5v45c" from " operating_conditions ("AB0.5v45c") { " . Can you please review the code

      #!/usr/bin/perl use strict; use warnings; use IO::All; use Data::Dumper; use feature 'say'; my @operating_cond; my @lines = io('file.txt')->chomp->slurp; #print Dumper \@lines; for my $i (0 .. $#lines) { if ($lines[$i] =~ /operating_conditions/) { #print "$lines[$i]\n"; @operating_cond=split (operating_conditions,$lines[$i]); @operating_cond=split ("{",$operating_cond[1]); @operating_cond=split (/\(/,$operating_cond[0]); @operating_cond=split (/\)/,$operating_cond[1]); # Insert at position 12, replace 0 elements. splice @lines, $i + 5, 0, 'default_operating_conditions : "@operat +ing_cond" ;'; last; # break loop } next; } print Dumper \@lines;

      Thank you for your help :)

        Hello again anirbanphys,

        See the updated version that contains solution to the hard-coded problem. Now the script will pick up the string withing the interesting line.

        Hope this helps. Let me know if you can not understand what the code does.

        BR / Thanos

        Seeking for Perl wisdom...on the process of learning...not there...yet!
      Thank you thanos1983 for your help.

      The above mentioned code will be working if we remove the "HARD CODED" "default_operating_conditions : "AB0.5v45c" ;". If you look at my code, I am doing some operations for getting "AB0.5v45c" from " operating_conditions ("AB0.5v45c") { " . Like,

      splice @lines, $i + 5, 0, 'default_operating_conditions : "$operating_ +cond[0]" ;';
      One more thing, how to avoid to print the very first "$VAR1 = [" section?

      Thank you for your help :)

        Hello again anirbanphys,

        Regarding the hard-coded part I have already replied to your question :). Regarding the first print simply commend out the line: # print Dumper \@lines;.

        Hope this helps, BR.

        Seeking for Perl wisdom...on the process of learning...not there...yet!
Re: How to add a new line after three or four lines from a pattern after getting that pattern
by jwkrahn (Monsignor) on Apr 03, 2019 at 19:23 UTC

    This appears to do what you require:

    #!/usr/bin/perl use strict; use warnings; if ( @ARGV != 1 ) { print "USAGE :: perl default_operating_condition_update.pl <<FILE> +>\n\n"; exit 1; } my $inputfile = $ARGV[ 0 ]; # input FILE mkdir 'finallib' unless -d 'finallib'; open my $INFILE, '<', $inputfile or die "Can not open '$inputfile' bec +ause: $!"; open my $OPFILE, '>', "finallib/$inputfile" or die "Can not open 'fina +llib/$inputfile' because: $!"; while ( my $iline = <$INFILE> ) { print $OPFILE $iline; if ( $iline =~ /^ ( \s* ) operating_conditions \s* \( \s* ( .* ) \ +s* \) \s* { \s* $/x ) { my ( $leading_space, $operating_cond ) = ( $1, $2 ); until ( $iline =~ /^ \s* } \s* $/x ) { $iline = <$INFILE>; print $OPFILE $iline; } print $OPFILE "${leading_space}default_operating_conditions : +$operating_cond ;\n"; } }
      Hello jwkrahn,

      I got all the correct answer after posting my request. Yes all the MONKS had given me the right answer, but I really like to appreciate and thank you for doing the correction of my posted code and doing the modification in the accurate way. This is going to be an example for me to write the code for this kind of situation if I face again.

      Thank you :) for this great help

Re: How to add a new line after three or four lines from a pattern after getting that pattern
by clueless newbie (Deacon) on Apr 03, 2019 at 15:03 UTC
    I'm somewhat lazy so
    #!/usr/bin/env perl use Data::Dumper; use Regexp::Common; use 5.12.0; my $library_group_re=qr{ library\ * # "library" follow +ed by optional spaces ( # $1 capture (?<paren>$RE{balanced}{-parens=>'()'}) # balanced parenth +esis \ * # followed by opti +onal spaces (?<braces>$RE{balanced}{-parens=>'{}'}) # balanced braces ) # end $1 capture }x; my $operating_conditions_group_re=qr{ operating_conditions\ * # "operating_condi +tions" followed by optional spaces ( # $1 capture (?<paren>$RE{balanced}{-parens=>'()'}) # balanced parenth +esis \ * # followed by opti +onal spaces (?<braces>$RE{balanced}{-parens=>'{}'}) # balanced braces ) # end $1 capture }x; sub do_something_with_an_operating_conditions { #warn Data::Dumper->Dump([\@_],[qw(*_)]),' '; my (%captured)=@_; if (!exists $captured{paren} || ! exists $captured{braces}) { die "Should NOT happen!"; }; my $return='operating_conditions '; # process the stuff within the parenthesis - $return.="$captured{paren} "; # process the stuff within the braces $return.="$captured{braces}"; # The additional line. $return.="\n default_operating_conditions : ".substr($captured +{paren},1,-1)."\n"; return $return; }; sub do_something_with_a_library { #warn Data::Dumper->Dump([\@_],[qw(*_)]),' '; my (%captured)=@_; if (!exists $captured{paren} || ! exists $captured{braces}) { die "Should NOT happen!"; }; my $return='library '; # process the stuff within the parenthesis - $return.="$captured{paren}"; # process the stuff within the braces - operating conditions { (my $string=$captured{braces})=~ s{$operating_conditions_gr +oup_re}{do_something_with_an_operating_conditions(%+)}gex; $return.=" $string"; }; return $return; }; my $string; { # Because we want all of the data as a single string local $/; # Deal with string, which will be the entire file, replacing each +of library groups ($string=<DATA>) =~ s{$library_group_re}{do_something_with_a_libra +ry(%+)}gex; } print $string; __END__ library(and_gate) { delay_model : table_lookup ; date : "Fri Mar 15 03:44:39 " ; time_unit : 1ms ; voltage_unit : 1V ; current_unit : 1A ; operating_conditions ("AB0.5v45c") { process : 1 ; temperature : 45 ; voltage : 0.5 ; } input_voltage(default) { vi : 0 ; vh : 0.5 ; vim : 0 ; vin : 0.5 ; } }
      Hello clueless newbie,

      It is great to see you have resolved my problem in another way. I specially like the subroutine you have created, believe me I was going to post one more code issue which I was trying to resolve, but after looking and understanding your code I successfully accomplished the job :). What a moment of joy.

      Thank you. Thanks a TON

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2019-12-15 12:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?