Hİ;
I want you guys to prepare a script. I will attach output.txt file. ıt should check BSC and BCF name which are in INPUT.txt and SITE.txt.
After comparing , ıt should come out a SITE column in the OUTPUT.txt and there will be site names under of that column. This SITEs have BCF names so this site names which are in this column will come out after comparing OUTPUT.txt and SITE.txt.

       BADYK01      BCF-0081             ENVIR     2012-04-23  07:16:21.83                 DC POWER MAJOR             Not_ID: 14                         
       BADYK01      BCF-0101             ENVIR     2012-03-27  10:41:21.33                 DC POWER MAJOR             Not_ID: 10                         
       BADYK01      BCF-0141             ENVIR     2012-04-19  14:03:33.48                 DC POWER MAJOR             Not_ID: 366                        
       BADYK01      BCF-0161             ENVIR     2012-03-16  13:19:44.02    (25441) 7622 CABINET OPEN                                                    
       BADYK01      BCF-0161             ENVIR     2012-04-22  12:43:30.65                 DC POWER MINOR             Not_ID: 61410                      
       BADYK01      BCF-0171             ENVIR     2012-03-26  22:56:31.46                 DC POWER MAJOR             Not_ID: 17654                      
       BADYK01      BCF-0171             ENVIR     2012-03-26  22:56:34.76                 DC POWER MINOR             Not_ID: 17658                      
       BADYK01      BCF-0201             ENVIR     2012-03-14  01:36:23.91    (23067) 7622 CABINET OPEN                                                    
       BADYK01      BCF-0211             ENVIR     2012-04-15  08:20:41.98    (50075) 7622 CABINET OPEN                 

SITE BSC BCF ENVIR/EQUIPM ZAMAN ALAMLAR
AN0233 BADYK01 BCF-0041 ENVIR 2012-04-21 22:14:58.41 DC POWER MAJOR Not_ID: 196053
AN0518 BADYK01 BCF-0081 ENVIR 2012-04-23 07:16:21.83 DC POWER MAJOR Not_ID: 14
AN0539 BADYK01 BCF-0101 ENVIR 2012-03-27 10:41:21.33 DC POWER MAJOR Not_ID: 10
AN0604 BADYK01 BCF-0141 ENVIR 2012-04-19 14:03:33.48 DC POWER MAJOR Not_ID: 366

Recommended Answers

All 13 Replies

Hi abulut,
Foremost, when asking for people's help please and please be polite. Your statement

I want you guys to prepare a script. I will attach output.txt file

could put people who are willing to help off.
Secondly, Microsoft Excel or Openoffice Calc can easily get this kind of sorting done for you. Anyway, you know why you want it done with Perl.
Check the solution below I believe it has want you want.
Note: This Perl Script, site.txt and input.txt must either be in the same directory or you must specify both site.txt and input.txt path in your Perl Script.

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

my %has_site;
my ( $site_file, $input_file ) = qw(site.txt input.txt);
open my $fh, '<', $site_file or die "can't open this file:$!";
while (<$fh>) {
s{^\s+}{};
chomp;
my ( $bsc, $bcf, $site ) = split /\s+/, $_;
    $has_site{$site} = $bsc . '  ' . $bcf;
}
close $fh or die "can't close file:$!";

my $heading = "SITE";

open my $fh2, '>', 'output_file.txt'
  or die "can't open this file:$!";    # output file
open $fh, '<', $input_file or die "can't open this file:$!";
$heading .= <$fh>;
print $fh2 $heading;
while (<$fh>) {
s{^\s+}{};
chomp;
my ( $bsc, $bcf ) = split /\s+/, $_;
my $match = $bsc . '  ' . $bcf;
    foreach my $site ( sort keys %has_site ) {
        print $fh2 $site, " " x length($site), $_, $/
          if $match eq $has_site{$site};
    }
}
close $fh  or die "can't close file:$!";
close $fh2 or die "can't close file:$!";

Hope this helps.

Hi,
Thanks for helping .. could you pls order them time by time. Also they should be from the new time to last time

Thanks for helping .. could you pls order them time by time. Also they should be from the new time to last time

abulut, Do you mean you want them ordered by a combination of date and time? Should 2012-03-16 14:29:54.61 print before (above) 2012-04-23 07:16:21.83 for example? Normally we order by date and time, not time alone.

Another question for abulut. I see lines in INPUT.txt that include BADYK01 BCF-1621 and BADYK01 BCF-3000 but I don't find any BCF-1621 or BCF-3000 in the site.txt file. Do you want these lines output with no site?

Yes they should come out by an order.
For example 2012-04-16 will be the above of 2012-03-15. I meant the newest alarm will be top and the other and the other.
Thanks

yes thanks

Another question for abulut. I see lines in INPUT.txt that include BADYK01 BCF-1621 and BADYK01 BCF-3000 but I don't find any BCF-1621 or BCF-3000 in the site.txt file. Do you want these lines output with no site?

Another question for abulut. I see lines in INPUT.txt that include BADYK01 BCF-1621 and BADYK01 BCF-3000 but I don't find any BCF-1621 or BCF-3000 in the site.txt file. Do you want these lines output with no site?

Hi abulut,
Check the script below. It should order your filtered sites file from your input file from recent to later date.

Please note I have not included the bsc in the input file that has no corresponding line in the site file. It basically, my first program ordered in date as this request indicated:

could you pls order them time by time. Also they should be from the new time to last time

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

    my %has_site;
    my ( $site_file, $input_file ) = qw(site.txt input.txt);
    open my $fh, '<', $site_file or die "can't open this file:$!";
    while (<$fh>) {
        s{^\s+}{};
        chomp;
        my ( $bsc, $bcf, $site ) = split /\s+/, $_;
        $has_site{$site} = $bsc . '  ' . $bcf;
    }
    close $fh or die "can't close file:$!";

    open $fh, '<', $input_file or die "can't open this file:$!";
    my $alarm_date = do { local $/; <$fh> };
    close $fh or die "can't close file:$!";

    my %has_date;
    my $heading = "SITE ";
    foreach ( split /\n/, $alarm_date ) {
    $heading .= $_ if /\bBSC/;
    if (/.+?(\d{4}\-\d{2}\-\d{2}).+?/g) {
        my $date = $1;
    s{^\s+}{};
    my ( $bsc, $bcf ) = split /\s+/, $_;
    my $match = $bsc . '  ' . $bcf;
    while ( my ( $key, $value ) = each %has_site ) {
        if ( $match eq $value ) {
            push @{ $has_date{$date} }, $key, "\t", $_, $/;
        }
     }
    }
   }

    open $fh, '>', 'output_file.txt' or die "can't open file:$!";
        print $fh $heading, $/;
        print $fh @{ $has_date{$_} } for sort { $b cmp $a } keys %has_date;
    close $fh or die "can't close file:$!";

Thanks! Could you pls design a little bit? You made it come out from newest date but not from newest time. I meant 2012-03-23 09:10 will be the above of 2012-03-23 10:23.
Besides this last one I want is to be deleted red line part. Could you pls delete the part that draw red line and make a blank between time and alarms?
Thanks

The following works if you have the Tie::File module. If you don't have it you can find it on CPAN.

#!/usr/bin/perl
use warnings;
use strict;
my %has_site;
my ( $site_file, $input_file ) = qw(site.txt INPUT.txt);

open my $fh, '<', $site_file or die "can't open this file:$!";
while (<$fh>) {
    s{^\s+}{};
    s{\s+$}{};#I have linux so chomp doesn't remove CR/LF for me
    my ( $bsc, $bcf, $site ) = split /\s+/, $_;
    $has_site{$bsc . '  ' . $bcf} = $site;#I prefer looking up with bsc and bcf as key
}
close $fh or die "can't close file:$!";

open my $fh2, '>', 'OUTPUT.txt'
  or die "can't open this file:$!";    # output file

open $fh, '<', $input_file or die "can't open this file:$!";
my $hdrs = <$fh>;
$hdrs =~ s{^\s+}{};
$hdrs =~ s{\s+$}{};#I have linux so chomp doesn't remove CR/LF for me
$hdrs = 'SITE         ' . $hdrs;
$hdrs =~ s{\s+$}{};#Remove CR/LF
print $fh2 $hdrs, "\n";

while (<$fh>) {
    s{^\s+}{};
    s{\s+$}{};#I have linux so chomp doesn't remove CR/LF for me
    s{\(\d\d\d\d\d\) \d\d\d\d}{            };#Remove unwanted (25441) 7622 etc.
    my ( $bsc, $bcf ) = split /\s+/, $_;
    my $key = $bsc . '  ' . $bcf;
    my $site;
    if (exists $has_site{$key}){
        $site = $has_site{$key};
    }
    else{
        $site = '______'
    }
    print $fh2 $site, " " x length($site), $_, "\n";

}
close $fh  or die "can't close file:$!";
close $fh2 or die "can't close file:$!";

#Now you want to sort OUTPUT.txt
#This should really be a separate script
undef %has_site; #Reclaim memory space
use Tie::File;
tie my @array, 'Tie::File', 'OUTPUT.txt' or die "Failed to tie 'OUTPUT.txt': $!";
my $save_headers = shift @array;#Remove and save first line of output

@array = sort by_date_time @array;
unshift @array, $save_headers;#Restore first line of output

untie @array;

sub by_date_time{
    $a =~ m/(\d\d\d\d-\d\d-\d\d\s+\d\d:\d\d)/;
    my $dta = $1;

    $b =~ m/(\d\d\d\d-\d\d-\d\d\s+\d\d:\d\d)/;
    my $dtb = $1;

    $dta cmp $dtb;
}

Thanks for script!but it doesn't work perfectly. Times are mixing. The thing that I want is alarms to come out by an order. The newest alarm will be the top!
About red line seperated part will be deleted. also between bcf and time column will be seperated with 3 steps blanks. Last thing is that I want to see how many alarms are there. Output must come out like Total alarms=156 which is written behind of all!

Could you pls do that?
Thanks a lot!

Hi abulut,
People don't have to do all the jobs for you. Do they? d5e5 has given you a good program, I have shown you some too. All you needed to do is put them together. The answer you so seek is obvious.

Moreover, I don't think you really know what you wanted from the start, you kept changing the 'goal post in the middle of the game'. I think it will be better if you make your intentions known from the start. Even when d5e5 suggested some output to you, you bought it but never reflected in the ouput you have been showing ever since. So the question is what do you want? And if that is not different from all you have mentioned hitherto, I think you have more than want you need to actualize your output. From the scripts written thus far.

If you want people to help you, you also show them what you have tried so far. :(

First, I agree with 2teez that what when we write scripts we present them as examples of ways to do something you ask us how to do. I can't give you perfect solutions that will work without your having to make your own changes to adapt them to your requirements.

Second, my subroutine to sort the dates and times can be improved. If you replace the by_date_time subroutine with the following it should sort the report lines in descending order which I believe is what you want. (I included the statement for sorting in ascending order in a comment.)

sub by_date_time{
    my ($dta, $dtb);
    my @flds_a = split /\s+/, $a;
    if (@flds_a > 4){
        $dta = join ' ', @flds_a[4,5];
    }
    else{
        $dta = '';
    }

    my @flds_b = split /\s+/, $b;
    if (@flds_b > 4){
        $dtb = join ' ', @flds_b[4,5];
    }
    else{
        $dtb = '';
    }

    #$dta cmp $dtb;#Sort in Ascending Order
    $dtb cmp $dta;#Sort in Descending Order
}

Total alarms=156

And third, I see more than 1000 lines in the OUTPUT.txt (see attached file) so I don't understand why the total should be 156.

Thanks for helping guys.

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.