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

Hello Monks,

I have written a perl code which can merge two files according to the need. Now the intention is, the updated script should work for any number number of input files. The current script expects two input files to progress.

Let me explain you what the script is actually doing. The current script (please refer the code below) expects two input files, (please refer file_1 and file_2). The common part for both file_1 and file_2 is the header section. So the script

1. Will delete the header section from file_2.

2. Will merge updated file_2 with file_1 after deleting the last line (or should say, the " { " character from the last line from file_1 ).

Now the same process must go on for the extra provided inputs for the updated scripts. Can you folks please help me?

perl code

#!/usr/bin/perl use strict; use warnings; my $inputfile_one = $ARGV[0]; # input lib FILE my $inputfile_two = $ARGV[1]; # input lib FILE my $pin_name; my $counter = 0; if ($#ARGV!=1) { print "USAGE :: perl lib_marge.pl <<MAIN_LIB_FILE>> <<LIB_FILE_FOR +_MARGE>> \n\n" ; exit(1); } mkdir 'tmpdir' unless -d 'tmpdir'; mkdir 'finallib' unless -d 'finallib'; my $cmd_1 = "head -n -1 $inputfile_one > tmpdir/$inputfile_one ;"; # +Removing the last line from the main lib file system ($cmd_1); open (INFILE_TWO,"<","$inputfile_two") || die "Can not open LIB_FILE_F +OR_MARGE"; open (OFILE,">","tmpdir/Output.csv") || die "Can not open Input Text F +ile"; while (my $line = <INFILE_TWO>) { chomp $line; # print "$line \n"; if ($line =~m/^\s*cell\s*\(\"(.*)\"\)/g || $line =~m/^\s*cell\((.*) +\)/g || $line =~m/^\s*cell\s*\((.*)\)/g) { $pin_name = $1; chomp $pin_name; $counter = 1; } if ( $counter == 1 ) { print OFILE "$line\n"; } } close INFILE_TWO; close OFILE; my $cmd_2 = "cat tmpdir/$inputfile_one tmpdir/Output.csv > finallib/$i +nputfile_one ;rm -rf tmpdir"; system ($cmd_2);

file_1

library ("inv_add") { delay_model : lookup_table ; date : "Thu Jun 6 07:25:32 2019" ; lu_table_template (finc_valc) cell (lib_1) { dont_use : true ; dont_touch : true ; pin ("HIZIBI_IN_1") { direction : input ; clock : true ; max_transition : 1 ; capacitance : 12 ; } pin ("HIZIBI_79") { direction : output ; max_transition : 10; min_capacitance : 3 ; } pin ("HIZIBI_IN_1") { direction : input ; clock : true ; max_transition : 1 ; capacitance : 1 ; } pin ("HIZIBI_78") { direction : output ; max_transition : 10; min_capacitance : 34 ; capacitance : 34 ; } pin ("HIZIBI") { direction : output ; clock : true ; max_transition : 20; related_power_pin : VDD ; related_ground_pin : VSS ; timing () { cell_fall (into_f1) { index_1("1,2,3,4,5") ; index_2("1,2,3,4,5") ; values("13, 13, 14, 16, 18",\ "13, 14, 15, 16, 19",\ "14, 15, 16, 17, 20",\ "15, 15, 16, 18, 20",\ "15, 16, 17, 18, 21") ; } } } } }

file_2

library ("inv_add") { delay_model : lookup_table ; date : "Thu Jun 6 07:25:32 2019" ; lu_table_template (finc_valc) cell (lib_2) { dont_use : true ; dont_touch : true ; pin ("HIZIBI_98") { direction : output ; max_transition : 10; min_capacitance : 34 ; capacitance : 34 ; } } }

the output file should look like

library ("inv_add") { delay_model : lookup_table ; date : "Thu Jun 6 07:25:32 2019" ; lu_table_template (finc_valc) cell (lib_1) { dont_use : true ; dont_touch : true ; pin ("HIZIBI_IN_1") { direction : input ; clock : true ; max_transition : 1 ; capacitance : 12 ; } pin ("HIZIBI_79") { direction : output ; max_transition : 10; min_capacitance : 3 ; } pin ("HIZIBI_IN_1") { direction : input ; clock : true ; max_transition : 1 ; capacitance : 1 ; } pin ("HIZIBI_78") { direction : output ; max_transition : 10; min_capacitance : 34 ; capacitance : 34 ; } pin ("HIZIBI") { direction : output ; clock : true ; max_transition : 20; related_power_pin : VDD ; related_ground_pin : VSS ; timing () { cell_fall (into_f1) { index_1("1,2,3,4,5") ; index_2("1,2,3,4,5") ; values("13, 13, 14, 16, 18",\ "13, 14, 15, 16, 19",\ "14, 15, 16, 17, 20",\ "15, 15, 16, 18, 20",\ "15, 16, 17, 18, 21") ; } } } } cell (lib_2) { dont_use : true ; dont_touch : true ; pin ("HIZIBI_98") { direction : output ; max_transition : 10; min_capacitance : 34 ; capacitance : 34 ; } } }

Replies are listed 'Best First'.
Re: Merging of files with some edit.
by poj (Abbot) on Jun 25, 2019 at 13:00 UTC

    Try

    #!/usr/bin/perl use strict; use warnings; if (@ARGV < 2) { print "USAGE :: perl lib_marge.pl <<MAIN_LIB_FILE>> <<LIB_FILE_FOR +_MARGE>> \n\n" ; exit(1); } # read first file my $file1 = shift @ARGV; open IN,'<',$file1 or die "Can not open $file1 for input : $!"; print "$file1 opened for input\n"; my @file1 = <IN>; close IN; # remove last line pop @file1; # create new file my $outfile = 'Output.csv'; open OUT,'>',$outfile or die "Can not open $outfile for output : $!"; print "$outfile opened for output\n"; print OUT $_ for @file1; # add other files my $last; for my $infile (@ARGV){ open IN,'<',$infile or die "Can not open $infile for input : $!"; print "$infile opened for input\n"; my $flag = 0; my @lines = (); while (my $line = <IN>) { if ($line =~m/^\s*cell\s*\(\"(.*)\"\)/g || $line =~m/^\s*cell\((.*)\)/g || $line =~m/^\s*cell\s*\((.*)\)/g) { $flag = 1 } push @lines,$line if $flag; } close IN; $last = pop @lines; # remove last line print OUT $_ for @lines; } print OUT $last; # add last line close OUT;
    poj
      Thank you poj. Your given code is working well. Thank you so much for the help :).

      Regards,

      Anirban
Re: Merging of files with some edit.
by BillKSmith (Monsignor) on Jun 25, 2019 at 13:05 UTC
    I would look at the problem differently. Consider the following pseudo-code.
    Open output file for update. for each input file open current input file for input read header if (first input) {ouput header} read body output body close input file close output file

    You existing code already has nearly all the details. I think you can reorganize it yourself.

    Bill
Re: Merging of files with some edit.
by jwkrahn (Abbot) on Jun 25, 2019 at 19:35 UTC

    This appears to work correctly. Tested with four files.

    #!/usr/bin/perl use warnings; use strict; @ARGV > 1 or die "usage: $0 <<MAIN_LIB_FILE>> <<LIB_FILE_FOR_MARGE>> +\n\n"; open my $OUT, '>', 'final_file.dat' or die "Cannot open 'final_file.da +t' because: $!"; while ( <> ) { if ( /^\}$/ .. /^\s+.*\{$/ ) { print $OUT $_ if /^\s+.*\{$/; next; } print $OUT $_; } print $OUT "}\n";
      Yes it is also working accurately for multiple input files :). Thanks for sharing your thoughts jwkrahn :)
Re: Merging of files with some edit.
by Anonymous Monk on Jun 25, 2019 at 13:38 UTC

    Don't you care if the "headers" differ?

      The "headers" should be remain same across all the input files.
        The "headers" should be remain same ...

        "Should" is a wish. "Will" is a hope. "Won't" is the ultimate reality.


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

        It is my experience that the data frequently doesn't lives up to the user's expectation.