Tatman Tatman - 2 months ago 13
Perl Question

Unable to print some array elements in specific format in Perl



Having the following script to process a file and provide the output in the specific format.
I'm unable to the make the desired output table.

the input

#!/usr/bin/perl -w

use strict;
use warnings;
use Data::Dumper;
use diagnostics;

my $temp_M1SLP;
my @temp_M1SLP;

my $start_run = time();

my $header = "CODE NAME DST TY DAIS NO STAT TM TMW";
print "$header\n";

open( INFILE, "<Sample1.log" ) or die "Couldn't open file M1SLP.txt\n";
while ( my $line = <INFILE> ) {

chomp($line);
@temp_M1SLP = $line;

if ( $line =~ /^\d-\d+/ ) {
$temp_M1SLP[0] = ( substr $line, 0, 14 );
$temp_M1SLP[1] = ( substr $line, 15, 7 );
$temp_M1SLP[2] = ( substr $line, 28, 5 );
$temp_M1SLP[3] = ( substr $line, 35, 4 );

printf( "%-10s", $temp_M1SLP[0] );
printf( "%-10s", $temp_M1SLP[1] );
printf( "%-8s", $temp_M1SLP[2] );
printf( "%-5s", $temp_M1SLP[3] );
}

next if ( $line =~ /^ DAIS NO STAT TM TMW/ );

{
while ( $line =~ /^\s+\w+/ ) {

$temp_M1SLP[4] = ( substr $line, 15, 15 );
$temp_M1SLP[5] = ( substr $line, 32, 4 );
$temp_M1SLP[6] = ( substr $line, 38, 14 );
$temp_M1SLP[7] = ( substr $line, 55, 7 );
$temp_M1SLP[8] = ( substr $line, 62, 5 );

printf( "%-18s", $temp_M1SLP[4] );
printf( "%-6s", $temp_M1SLP[5] );
printf( "%-8s", $temp_M1SLP[6] );
printf( "%-8s", $temp_M1SLP[7] );
printf( "%-5s", "$temp_M1SLP[8]\n" );

$line = <INFILE>;
}
}
}

my $end_run = time();


The output file will be in this format

CODE NAME DST TY DAIS NO STAT TM TMW
2-2017 121CM02 AVA PP EP022CM02 1 DM-ACT-AVA 10
2-2017 121CM02 AVA PP EP032CM02 1 DM-BAT-BTA 20
2-2033 119LHR AVA PP HLR3EP03203 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP080 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP090 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP110 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP100 1 DM-BAT-BTA


The input file (Sampel1.txt) is as shown

CODE NAME DST TY
2-2017 121CM02 AVA PP

DAIS NO STAT TM TMW
EP022CM02 1 DM-ACT-AVA 10
EP032CM02 1 DM-BAT-BTA 20

2-2033 119LHR AVA PP

DAIS NO STAT TM TMW
HLR3EP03203 1 DM-BAT-BTA

2-2110 119A1AU AVA PP

DAIS NO STAT TM TMW
A1AUEP080 1 DM-BAT-BTA
A1AUEP090 1 DM-BAT-BTA
A1AUEP110 1 DM-BAT-BTA
A1AUEP100 1 DM-BAT-BTA


But currently, I got the output as following. Please your support to check the code and corrected

CODE NAME DST TY DAIS NO STAT TM TMW
2-2017 121CM02 AVA PP EP022CM02 1 DM-ACT-AVA 10
EP032CM02 1 DM-BAT-BTA 20

2-2033 119LHR AVA PP HLR3EP03203 1 DM-BAT-BTA
2-2110 119A1AU AVA PP A1AUEP080 1 DM-BAT-BTA
A1AUEP090 1 DM-BAT-BTA

A1AUEP110 1 DM-BAT-BTA

A1AUEP100 1 DM-BAT-BTA

Answer

My solution firstly skips all irrelevant lines. When a line starting with \d-\d+ is found (like 2-2017…) then the fields CODE, NAME, DST, and TY are only stored in global variables. I replaced your array @temp_M1SLP with explicit variable names for that.

When a line is found that looks like DAIS, NO, … (identified by a line with a word after whitespace), then the values from the preceding section (CODE, NAME, …) and the current values are printed.

My code more or less is a shuffled version of your code. However, I like Borodin's solution better as it is much more elegant.

#!/usr/bin/env perl

use strict;
use warnings 'all';

my $header = "CODE          NAME      DST     TY   DAIS                NO  STAT          TM     TMW";
print "$header\n";

my ( $code, $name, $dst, $ty );
open( INFILE, "<Sample1.log" ) or die "Couldn't open file Sample1.log\n";
while ( my $line = <INFILE> ) {

    chomp($line);

    # skip header, subheader, and empty lines:
    next if ( $line =~ /^CODE\s+NAME\s+DST\s+TY/ );
    next if ( $line =~ /^\s+DAIS\s+NO\s+STAT\s+TM\s+TMW/ );
    next if ( $line !~ /\S/ );

    # code section found? then remember the values
    # but don't print them yet.
    if ( $line =~ /^\d-\d+/ ) {
        $code = substr( $line, 0,  14 );
        $name = substr( $line, 15, 7 );
        $dst  = substr( $line, 28, 5 );
        $ty   = substr( $line, 35, 4 );
    }

    # line with DAIS, NO, ... found? then print the columns from
    # the code section _and_ the columns of this line:
    if ( $line =~ /^\s+\w+/ ) {
        my $dais = substr( $line, 15, 15 );
        my $no   = substr( $line, 32, 4 );
        my $stat = substr( $line, 38, 14 );
        my $tm   = substr( $line, 55, 7 );
        my $tmw  = substr( $line, 62, 5 );

        printf( "%-10s",  $code );    # from code section
        printf( "%-10s",  $name );    #        "
        printf( "%-8s",   $dst );     #        "
        printf( "%-5s",   $ty );      #        "
        printf( "%-18s",  $dais );    # from current line
        printf( "%-6s",   $no );      #        "
        printf( "%-8s",   $stat );    #        "
        printf( "%-8s",   $tm );      #        "
        printf( "%-5s\n", $tmw );     #        "
    }

}

Output

CODE          NAME      DST     TY   DAIS                NO  STAT          TM     TMW
2-2017        121CM02   AVA     PP   EP022CM02            1  DM-ACT-AVA            10   
2-2017        121CM02   AVA     PP   EP032CM02            1  DM-BAT-BTA    20           
2-2033        119LHR    AVA     PP   HLR3EP03203          1  DM-BAT-BTA                 
2-2110        119A1AU   AVA     PP   A1AUEP080            1  DM-BAT-BTA                 
2-2110        119A1AU   AVA     PP   A1AUEP090            1  DM-BAT-BTA                 
2-2110        119A1AU   AVA     PP   A1AUEP110            1  DM-BAT-BTA                 
2-2110        119A1AU   AVA     PP   A1AUEP100            1  DM-BAT-BTA