Hi,

I tried to make a script but I need some help from you guys.. ıt will be like a fixing..
The output which ı had from my script and my script were sent as an attachment.
1)Can i get that output as left aligned?
2)Besides can you guys make the space smaller from "ZAMAN" to "SAHA after deleting "***ALARM" ??
3)Last thing ı want is to be come the output in an order by timing? I mean the top of the written must be the newest date..?

I will be waiting for your answer..

Thank you
Adam

Recommended Answers

All 14 Replies

Rather than change your long complex script, you can run a second script that takes the resulting file as input, then modifies the spacing and sorts the lines.

#!/usr/bin/perl
use strict; 
use warnings; 

my $filename = 'KESIK_SEKTORLER.txt';
open my $fh, '<', $filename or die "Failed to open $filename: $!";

my @file = <$fh>; #Read file into array so you can sort
map s/\R//g, @file; #Remove Windows end-of-line characters because I have Linux

@file = sort sortsub @file;

foreach(@file){
    s/\s+/ /g;#Replace many spaces with one space
    s/^\s//;#Remove space at beginning of line
    print $_, "\n";
}

sub sortsub{
    my $date_pattern = '\d\d\d\d-\d\d-\d\d';
    my $time_pattern = '\d\d:\d\d:\d\d\.\d\d';
    my ($a_dt) = $a =~ m/($date_pattern\s+$time_pattern)/;
    my ($b_dt) = $b =~ m/($date_pattern\s+$time_pattern)/;
    #print "adt is $a_dt\tbdt is $b_dt\n";
    $a_dt = '9' x 23 unless defined $a_dt;
    $b_dt = '9' x 23 unless defined $b_dt;
    $b_dt cmp $a_dt;
}

I've tried that you did not run script. Can you check it again. as the following must be cut according to SEKTORLER.txt log.txt file.

My output txt
 BSC          BCF          DATE           TIME         SAHA        ALARM 
BCORK01      BCF-0021    2012-02-29     19:11:41.65   CO11801  BCH MISSING    
BCORK01      BCF-0021    2012-02-29     19:11:42.65   CO11802  BCH MISSSING  
BCORK01      BCF-0021    2012-02-29     19:11:43.65   CO11802  BCH MISSSING

I've tried that you did not run script. Can you check it again. as the following must be cut according to SEKTORLER.txt log.txt file.

My output txt
 BSC          BCF          DATE           TIME         SAHA        ALARM 
BCORK01      BCF-0021    2012-02-29     19:11:41.65   CO11801  BCH MISSING    
BCORK01      BCF-0021    2012-02-29     19:11:42.65   CO11802  BCH MISSSING  
BCORK01      BCF-0021    2012-02-29     19:11:43.65   CO11802  BCH MISSSING

Sorry, I don't understand what you mean by 'I've tried that you did not run script.' Also, you said previously 'the top of the written must be the newest date' but the sample output you show above has the most recent date + time at the bottom.

#!/usr/bin/perl
use strict; 
use warnings; 

my $date_pattern = '\d\d\d\d-\d\d-\d\d';
my $time_pattern = '\d\d:\d\d:\d\d\.\d\d';
my $filename = 'LOG.txt';
my %lines;#Save report lines to sort later

open my $fh, '<', $filename or die "Failed to open $filename: $!";

while (my $line = <$fh>){
    $line =~ s/\R//g; #Remove Windows end-of-line characters because I have Linux
    if ($line =~ m/^\s+(\w+\d\d)\s+(\w+-\d\d\d\d)\s+\w+\s+($date_pattern)\s+($time_pattern)/){
        my ($bsc,$bcf,$date,$time) = ($1,$2,$3,$4);
        my $saha = get_saha();
        next if $saha eq '***SAHA NOT FOUND***';
        my $alarm = get_alarm();
        next if $alarm eq '***Alarm NOT FOUND***';
        #print "$bsc\t$bcf\t$date\t$time\t$saha\t$alarm\n";
        my $ctr = sprintf '%04d', $.;
        $lines{$date . $time . $ctr}{'bsc'} = $bsc;
        $lines{$date . $time . $ctr}{'bcf'} = $bcf;
        $lines{$date . $time . $ctr}{'date'} = $date;
        $lines{$date . $time . $ctr}{'time'} = $time;
        $lines{$date . $time . $ctr}{'saha'} = $saha;
        $lines{$date . $time . $ctr}{'alarm'} = $alarm;
    }
}

print " BSC          BCF          DATE           TIME         SAHA        ALARM \n";
foreach (sort {$b cmp $a} keys %lines){
    my @flds = ($lines{$_}{'bsc'}, $lines{$_}{'bcf'},
                $lines{$_}{'date'}, $lines{$_}{'time'},
                $lines{$_}{'saha'}, $lines{$_}{'alarm'});
    my $line = sprintf '%-10s%-12s%-15s%-16s%-14s%-12s', @flds;
    
    print $line, "\n";
}

sub get_saha{
    while (my $line = <$fh>){
        $line =~ s/\R//g; #Remove Windows end-of-line characters because I have Linux
        if ($line =~ m/^\*\*\*\s+ALARM\s+(\w+)/){
            return $1;
        }
        if ($line =~ m/^\s+(\w+\d\d)\s+(\w+-\d\d\d\d)\s+\w+\s+($date_pattern)\s+($time_pattern)/){
            return '***SAHA NOT FOUND***';
        }
    }
}

sub get_alarm{
    while (my $line = <$fh>){
        $line =~ s/\R//g; #Remove Windows end-of-line characters because I have Linux
        if ($line =~ m/^\s+\(\d+\)\s+\d+\s+([\w\s]+)$/){
            return $1;
        }
        if ($line =~ m/^\s+(\w+\d\d)\s+(\w+-\d\d\d\d)\s+\w+\s+($date_pattern)\s+($time_pattern)/){
            return '***Alarm NOT FOUND***';
        }
    }
}

Outputs:

BSC          BCF          DATE           TIME         SAHA        ALARM 
BURFK01   BCF-0931    2012-02-29     21:47:39.21     TRX           FAILURE IN SENDING SYSTEM INFORMATION TO BTS SITE               
BERZK01   BCF-2081    2012-02-29     21:47:02.77     ER19391       BCCH MISSING                                                    
BKAYK01   BCF-0841    2012-02-29     21:45:56.08     KY12851       BCCH MISSING                                                    
BURFK01   BCF-0441    2012-02-29     21:45:17.15     TRX           FAILURE IN SENDING SYSTEM INFORMATION TO BTS SITE               
BMRDK01   BCF-0531    2012-02-29     21:45:02.51     MR38321       BCCH MISSING                                                    
BMUSK01   BCF-0181    2012-02-29     21:44:46.32     MS39011       BCCH MISSING                                                    
BURFK01   BCF-0441    2012-02-29     21:44:15.21     TRX           FAILURE IN SENDING SYSTEM INFORMATION TO BTS SITE               
BURFK01   BCF-0441    2012-02-29     21:44:15.19     SU65381       BCCH MISSING                                                    
BELAK01   BCF-0591    2012-02-29     21:40:56.28     TRX           FAILURE IN SENDING SYSTEM INFORMATION TO BTS SITE               
BELAK01   BCF-0591    2012-02-29     21:40:56.26     EL37521       BCCH MISSING                                                    
BDIYK01   BCF-1141    2012-02-29     21:40:10.81     DI64581       BCCH MISSING                                                    
BMRDK01   BCF-0751    2012-02-29     21:28:27.05     MR56421       BCCH MISSING                                                    
BSRNK01   BCF-0131    2012-02-29     21:22:32.86     SR11501       BCCH MISSING                                                    
BMRDK01   BCF-0531    2012-02-29     21:05:03.57     MR38323       BCCH MISSING                                                    
BERZK01   BCF-2081    2012-02-29     21:00:18.70     ER19392       BCCH MISSING                                                    
BTOKK01   BCF-0211    2012-02-29     20:56:03.89     TO20882       BTS FAULTY                                                      
BMALK01   BCF-0171    2012-02-29     20:50:29.78     MA24872       BCCH MISSING                                                    
BAGRK01   BCF-0991    2012-02-29     20:34:01.72     AG05041       BCCH MISSING                                                    
BVANK02   BCF-0931    2012-02-29     20:15:38.78     TRX           FAILURE IN SENDING SYSTEM INFORMATION TO BTS SITE               
BVANK02   BCF-0931    2012-02-29     20:15:12.62     VA48651       BCCH MISSING                                                    
BBATK01   BCF-0441    2012-02-29     20:08:11.83     BT08691       BCCH MISSING                                                    
BSRTK01   BCF-0541    2012-02-29     19:45:11.70     SI26441       BCCH MISSING                                                    
BURFK01   BCF-0611    2012-02-29     19:32:49.51     TRX           FAILURE IN SENDING SYSTEM INFORMATION TO BTS SITE               
BTOKK01   BCF-0511    2012-02-29     18:20:22.60     TO22041       BCCH MISSING                                                    
BELAK01   BCF-0441    2012-02-29     17:46:46.10     EL37213       BCCH MISSING                                                    
BMALK02   BCF-0491    2012-02-28     19:24:52.62     MA24101       BCCH MISSING                                                    
BELAK01   BCF-1241    2012-02-28     02:17:03.26     EL38313       BCCH MISSING                                                    
BSRNK01   BCF-0131    2012-02-23     10:12:18.66     SR11502       BCCH MISSING                                                    
BAMSK02   BCF-0061    2012-02-22     16:49:22.28     TRX           FAILURE IN SENDING SYSTEM INFORMATION TO BTS SITE               
BKSTK02   BCF-0161    2012-02-21     02:26:13.56     TRX           FAILURE IN SENDING SYSTEM INFORMATION TO BTS SITE               
BMRDK01   BCF-0201    2012-02-21     01:43:51.13     TRX           FAILURE IN SENDING SYSTEM INFORMATION TO BTS SITE               
BAHLK03   BCF-1461    2012-02-16     02:58:22.94     TRX           FAILURE IN SENDING SYSTEM INFORMATION TO BTS SITE

Thanks for helping. However we only want to get a output which is related with 'BCCH MISSING' and ı want it come out time by time.. ı mean from new time to old time.
can you help me ?

My output txt 
BSC          BCF          DATE           TIME         SAHA        ALARM 
BCORK01      BCF-0021    2012-02-29     19:11:41.65   CO11801  BCH MISSING    
BCORK01      BCF-0021    2012-02-29     19:11:42.65   CO11802  BCH MISSSING  
BCORK01      BCF-0021    2012-02-29     19:11:43.65   CO11802  BCH MISSSING
#!/usr/bin/perl
use strict; 
use warnings; 
use constant {
    ASC     => 1,
    DESC    => -1
};

my $date_pattern = '\d\d\d\d-\d\d-\d\d';
my $time_pattern = '\d\d:\d\d:\d\d\.\d\d';
my $filename = 'LOG.txt';
my %lines;#Save report lines to sort later

open my $fh, '<', $filename or die "Failed to open $filename: $!";

while (my $line = <$fh>){
    $line =~ s/\R//g; #Remove Windows end-of-line characters because I have Linux
    if ($line =~ m/^\s+(\w+\d\d)\s+(\w+-\d\d\d\d)\s+\w+\s+($date_pattern)\s+($time_pattern)/){
        my ($bsc,$bcf,$date,$time) = ($1,$2,$3,$4);
        my $saha = get_saha();
        next if $saha eq '***SAHA NOT FOUND***';
        my $alarm = get_alarm();
        next if $alarm eq '***Alarm NOT FOUND***';
        #print "$bsc\t$bcf\t$date\t$time\t$saha\t$alarm\n";
        my $ctr = sprintf '%04d', $.;
        $lines{$date . $time . $ctr}{'bsc'} = $bsc;
        $lines{$date . $time . $ctr}{'bcf'} = $bcf;
        $lines{$date . $time . $ctr}{'date'} = $date;
        $lines{$date . $time . $ctr}{'time'} = $time;
        $lines{$date . $time . $ctr}{'saha'} = $saha;
        $lines{$date . $time . $ctr}{'alarm'} = $alarm;
    }
}

print " BSC          BCF          DATE           TIME         SAHA        ALARM \n";

#To change sort from ascending to descending sequence replace ASC with DESC
#in the following line.
foreach (sort {($a cmp $b) * ASC} keys %lines){
    my @flds = ($lines{$_}{'bsc'}, $lines{$_}{'bcf'},
                $lines{$_}{'date'}, $lines{$_}{'time'},
                $lines{$_}{'saha'}, $lines{$_}{'alarm'});
    my $line = sprintf '%-10s%-12s%-15s%-16s%-14s%-12s', @flds;
    
    #print $line, "\n";#Change this statement to the following
    print $line, "\n" if $lines{$_}{'alarm'} =~ 'BCCH MISSING';
}

sub get_saha{
    while (my $line = <$fh>){
        $line =~ s/\R//g; #Remove Windows end-of-line characters because I have Linux
        #Changed the following to include alarms preceded by one or more asterixes *
        if ($line =~ m/^\*+\s+ALARM\s+(\w+)/){
            return $1;
        }
        if ($line =~ m/^\s+(\w+\d\d)\s+(\w+-\d\d\d\d)\s+\w+\s+($date_pattern)\s+($time_pattern)/){
            return '***SAHA NOT FOUND***';
        }
    }
}

sub get_alarm{
    while (my $line = <$fh>){
        $line =~ s/\R//g; #Remove Windows end-of-line characters because I have Linux
        if ($line =~ m/^\s+\(\d+\)\s+\d+\s+([\w\s]+)$/){
            return $1;
        }
        if ($line =~ m/^\s+(\w+\d\d)\s+(\w+-\d\d\d\d)\s+\w+\s+($date_pattern)\s+($time_pattern)/){
            return '***Alarm NOT FOUND***';
        }
    }
}

Outputs:

BSC          BCF          DATE           TIME         SAHA        ALARM 
BELAK01   BCF-0571    2012-02-23     01:32:56.77     EL37503       BCCH MISSING                                                    
BSRNK01   BCF-0131    2012-02-23     10:12:18.66     SR11502       BCCH MISSING                                                    
BELAK01   BCF-1201    2012-02-29     13:13:52.33     EL04941       BCCH MISSING                                                    
BMARK01   BCF-0551    2012-02-29     15:40:44.45     KM33611       BCCH MISSING                                                    
BTOKK01   BCF-0511    2012-02-29     18:20:22.60     TO22041       BCCH MISSING                                                    
BBATK01   BCF-0441    2012-02-29     20:08:11.83     BT08691       BCCH MISSING                                                    
BERZK01   BCF-2081    2012-02-29     21:00:18.70     ER19392       BCCH MISSING                                                    
BSRNK01   BCF-0131    2012-02-29     21:22:32.86     SR11501       BCCH MISSING                                                    
BURFK01   BCF-0181    2012-02-29     21:23:51.37     SU65261       BCCH MISSING                                                    
BMRDK01   BCF-0751    2012-02-29     21:28:27.05     MR56421       BCCH MISSING                                                    
BDIYK01   BCF-1141    2012-02-29     21:40:10.81     DI64581       BCCH MISSING                                                    
BELAK01   BCF-0591    2012-02-29     21:40:56.26     EL37521       BCCH MISSING                                                    
BMUSK01   BCF-0181    2012-02-29     21:44:46.32     MS39011       BCCH MISSING                                                    
BMRDK01   BCF-0531    2012-02-29     21:45:02.51     MR38321       BCCH MISSING                                                    
BKAYK01   BCF-0841    2012-02-29     21:45:56.08     KY12851       BCCH MISSING                                                    
BURFK01   BCF-0931    2012-02-29     21:46:47.26     SU59131       BCCH MISSING                                                    
BERZK01   BCF-2081    2012-02-29     21:47:02.77     ER19391       BCCH MISSING

hi
we tried your script but there is a missing on it. for example ; normally it should find 50 'BCCH MISSING' but 11 'BCCH MISSING' came out in output..
could you please check it out again?

#!/usr/bin/perl
use strict; 
use warnings; 
use constant {
    ASC     => 1,
    DESC    => -1
};

my $date_pattern = '\d\d\d\d-\d\d-\d\d';
my $time_pattern = '\d\d:\d\d:\d\d\.\d\d';
my $filename = 'LOG.txt';
my %lines;#Save report lines to sort later

my $filenane="KESIK_SEKTOR.txt";
open my $fh, '<', $filename or die "Failed to open $filename: $!";


open fp2, ">$filenane" or die "Cannot find $filenane for read\n :$!";

while (my $line = <$fh>){
    #$line =~ s/\R//g; #Remove Windows end-of-line characters because I have Linux
    if ($line =~ m/^\s+(\w+\d\d)\s+(\w+-\d\d\d\d)\s+\w+\s+($date_pattern)\s+($time_pattern)/){
        my ($bsc,$bcf,$date,$time) = ($1,$2,$3,$4);
        my $saha = get_saha();
        next if $saha eq '***SAHA NOT FOUND***';
        my $alarm = get_alarm();
        next if $alarm eq '***Alarm NOT FOUND***';
        #print "$bsc\t$bcf\t$date\t$time\t$saha\t$alarm\n";
        my $ctr = sprintf '%04d', $.;
        $lines{$date . $time . $ctr}{'bsc'} = $bsc;
        $lines{$date . $time . $ctr}{'bcf'} = $bcf;
        $lines{$date . $time . $ctr}{'date'} = $date;
        $lines{$date . $time . $ctr}{'time'} = $time;
        $lines{$date . $time . $ctr}{'saha'} = $saha;
        $lines{$date . $time . $ctr}{'alarm'} = $alarm;
    }
}

print fp2" BSC          BCF          DATE           TIME         SAHA        ALARM \n";

#To change sort from ascending to descending sequence replace ASC with DESC
#in the following line.
foreach (sort {($a cmp $b) * ASC} keys %lines){
    my @flds = ($lines{$_}{'bsc'}, $lines{$_}{'bcf'},
                $lines{$_}{'date'}, $lines{$_}{'time'},
                $lines{$_}{'saha'}, $lines{$_}{'alarm'});
    my $line = sprintf '%-10s%-12s%-15s%-16s%-14s%-12s', @flds;
    
    #print $line, "\n";#Change this statement to the following
    print fp2 $line, "\n" if $lines{$_}{'alarm'} =~ 'BCCH MISSING';
}

sub get_saha{
    while (my $line = <$fh>){
        #$line =~ s/\R//g; #Remove Windows end-of-line characters because I have Linux
        #Changed the following to include alarms preceded by one or more asterixes *
        if ($line =~ m/^\*+\s+ALARM\s+(\w+)/){
            return $1;
        }
        if ($line =~ m/^\s+(\w+\d\d)\s+(\w+-\d\d\d\d)\s+\w+\s+($date_pattern)\s+($time_pattern)/){
            return '***SAHA NOT FOUND***';
        }
    }
}

sub get_alarm{
    while (my $line = <$fh>){
        #$line =~ s/\R//g; #Remove Windows end-of-line characters because I have Linux
        if ($line =~ m/^\s+\(\d+\)\s+\d+\s+([\w\s]+)$/){
            return $1;
        }
        if ($line =~ m/^\s+(\w+\d\d)\s+(\w+-\d\d\d\d)\s+\w+\s+($date_pattern)\s+($time_pattern)/){
            return '***Alarm NOT FOUND***';
        }
    }
}

Sorry, I was able to answer your original question about how to sort lines by date and time but I'm not able to filter your input data in the right way to give exactly the output you want. You may need to hire an expert to do that.

I had to guess what characters to look for to know when the end of an input record occurs because each input record has several lines. The following script prints 50 BCCH MISSING lines on my computer.

#!/usr/bin/perl
use strict; 
use warnings;

use constant {
    ASC     => 1,
    DESC    => -1
};

my $date_pattern = '\d\d\d\d-\d\d-\d\d';
my $time_pattern = '\d\d:\d\d:\d\d\.\d\d';
my $filename = 'LOG.txt';

my $filenane="KESIK_SEKTOR.txt";
open my $fh, '<', $filename or die "Failed to open $filename: $!";

use constant {WINDOWS_LINE_END_CHAR => chr(13) . chr(10)};
my $record_separator = WINDOWS_LINE_END_CHAR x 2;
my $ctr = 0;
my %lines;#Save report lines to sort later
while (my $aref = get_next_rec($record_separator)){
    my ($bsc,$bcf,$date,$time,$saha,$alarm) = @$aref;
    $lines{$date . $time. $ctr++} = $aref if $alarm eq 'BCCH MISSING';
}

open my $fp2, '>', $filenane or die "Cannot open $filenane for output\n :$!";
print $fp2 " BSC          BCF          DATE           TIME         SAHA        ALARM \n";
foreach (sort {($a cmp $b) * ASC} keys %lines){
    my @flds = @{$lines{$_}};
    my $line = sprintf '%-10s%-12s%-15s%-16s%-14s%-12s', @flds;
    print $fp2 $line, "\n";
}

sub get_next_rec{
    local $/ = shift;
    while (my $r = <$fh>){
        my $dtrec = $r =~ m/^\s+([\w]+)\s+(\w+-\d+).+($date_pattern)\s+($time_pattern)/;
        if ($dtrec){
            my ($bsc,$bcf,$date,$time) = ($1,$2,$3,$4);
            
            my $saha;
            if ($r =~ m/([A-Z]{2}\d{5})/m){
                $saha = $1;
            }
            else{
                $saha = 'SahaNotFound'
            }
            
            my $alarm;
            if ($r =~ m/ALARM.+\d\d\d\d\s((\w+\s?)+\w+)/ms){
                $alarm = $1;
            }
            else{
                $alarm = 'ALARMNotFound'
            }
            return [($bsc,$bcf,$date,$time,$saha,$alarm)];
        }
        else{
            next;
        }
    }
}

@abulut, I received a private message from you saying you get no output when you run my script, but I can't understand why not. When I run the above script on my computer I see 50 lines in the output file named KESIK_SEKTOR.txt which I have attached to this message. I don't know why this would not work on your computer. I believe your operating system is Windows and mine is Linux, but I don't know why this would make a difference. I don't have Windows on my computer so I don't think there is anything else I can do to make it work under Windows.

I just tested your script under Win7x64 and it only produces the headers (BSC BCF DATE TIME SAHA ALARM) but nothing else. Instead of chasing down some obscure bug related to the windows OS it should be faster to just run this under Linux/some sort of VM, as the script evidently works for that platform.

I suspect the statements that need to change to make it run under Windows are one of the following two:
use constant {WINDOWS_LINE_END_CHAR => chr(13) . chr(10)}; my $record_separator = WINDOWS_LINE_END_CHAR x 2;

The input file records contain newline characters and Perl assumes newline as the default record separator. When I examine the input file (LOG.txt) it appears to me that each true record ends in a double set of the Windows newline characters. Unlike Linux, Windows ends its lines with a combination of Carriage Return and Line Feed characters. I think that newline \n means just Line Feed in Linux and Carriage Return + Line Feed in Windows. That's why I specify the line separator for input (not output) explicitly. But for some reason running the script in Windows hides or modifies the newline characters. I don't know why and I would have to experiment with various line separators and test under Windows, which I don't have.

It looks like a long complex script to debug, but I suspect that getting a simple script reading multi-line records to work under Windows would reveal the secret to getting this one to work.

I suspect the statements that need to change to make it run under Windows are one of the following two

I tested the second line before creating my first post but nothing changed. Turns out i overlooked the x 2 for some reason.
If you replace those lines with the following it works without problems.
my $record_separator = "\n\n";

commented: Thanks for the help! I couldn't test this properly without Windows. +8

If you replace those lines with the following it works without problems.
my $record_separator = "\n\n";

When I make that change the script prints headings only, because I have Linux. I hope abulut is still reading this, because I think you (replic) have solved the problem of running it under Windows.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.