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

Hi , Here is my code which i wrote to get Comma seperated output.
#!/usr/bin/perl print "Hello, World...\n"; my $logFile = $ARGV[0]; die "usage: $0 <logFile>" unless $logFile; die "Logfile $logFile doesn't exist" unless -f "$logFile"; open(my $log, "<", $logFile) or die "Can't open $logFile for reading." +; print "Processing file $logFile...\n"; #my $authenticates = {}; my $n = 0; my $Time_Stamp ; my $User_Name; my $Success; my $Failure; my $ErrorCode; my $ErrorMsg; while(my $line = <$log>) { $n++; $line =~ tr/\r\n//d; if ($line =~ /^(.*)INFO:.*recvd AA_BIN_MSG_GET_WLT/) { $Time_Stamp = $1; while ( $line = <$log> ) { if ($line =~ /recvd AA_BIN_MSG_VER_CHG$/) { while ( $line = <$log>) { if ($line =~ /Cert.*UserID=(\d+)/) { $User_Name = $1 ? $1 : "NULL" ; } } while ( $line = <$log> ) { if ($line =~ /ArcotID Auth SUCCESS/) { $Success = "Success"; } } while ( $line = <$log> ) { if ($line =~ /Auth fail due to signature verificat +ion/) { $Failure = "Failure"; } } while ( $line = <$log> ) { if ($line =~ /Authentication mechanism returned \[ +(\d+)\]/) { $ErrorCode = $1; } } while ( $line = <$log>) { if ($line =~ /(Auth fail due to signature verifica +tion.)/) { $ErrorMsg = $1 ? $1 : "Null"; } } }print "$Time_Stamp , $User_Name , $Success , $Failure , $ +ErrorCode , $ErrorMsg \n"; next; } } }
I am getting all the values in the variables but the final outcome prints it only once not for all and the formating suggestions in my code is also needed. Kindly sugegst me something according to my code. The snippet of the logfile is like this.
Native Server: recvd AA_BIN_MSG_GET_WLT Fri May 29 18:31:53.467 2009 Morocco Standard Time INFO: pid 3216 t +id 2672: 17: 132357: ArAuthFrameworkImpl::doAuth::11:132357:: Authent +ication mechanism returned [1] for AuthIdentity [;ARCARD] Fri May 29 18:31:53.467 2009 Morocco Standard Time INFO: pid 3216 t +id 2672: 170: 132357: Handle_NSPAdvice:: Handling NSPAdvice for mecha +nism [4] Fri May 29 18:31:53.467 2009 Morocco Standard Time INFO: pid 3216 t +id 2672: 17: 132357: ArAuthFrameworkImpl::doPostAuth::11:132357:: Aut +hentication mechanism returned [1] for AuthIdentity [01302904] Fri May 29 18:31:53.482 2009 Morocco Standard Time INFO: pid 3216 t +id 2672: 60: 132357: Sending Continue with challenge Fri May 29 18:31:53.482 2009 Morocco Standard Time INFO: pid 3216 t +id 2672: 61: 132357: Packet being sent Fri May 29 18:31:53.482 2009 Morocco Standard Time INFO: pid 3216 t +id 2672: 60: 0: Packet Sent (MsgType:110, Size: 1564 Bytes). Fri May 29 18:31:53.498 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 60: 0: Packet Received (MsgType:109, Size: 1463 Bytes). Fri May 29 18:31:53.498 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 60: 0: Locale Name[en], Locale ID[1] Fri May 29 18:31:53.498 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 0: 132358: Message: ArAuthBinaryAuthRequestMgr::setSecurityI +nfo: security_info_offset [0] is invalid. Assuming security info not +available. Fri May 29 18:31:53.498 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 17: 132358: Using session identifier [11:132358] Fri May 29 18:31:53.498 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 17: 132358: ArAuthFrameworkImpl::doPreAuth::11:132358:: Auth +entication mechanism returned [0] for AuthIdentity [] Fri May 29 18:31:53.498 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 170: 132358: Arcot Native Server: recvd AA_BIN_MSG_VER_CHG Fri May 29 18:31:53.498 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 170: 132358: Cert Subject String....:[CN=01302904;O=MLS; Use +rID=0123456; CardName=ARCARD] Fri May 29 18:31:53.498 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 170: 132358: Cert issuer............:[] Fri May 29 18:31:53.498 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 170: 132358: Cert serial String.....:[e93b] Fri May 29 18:31:53.498 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 170: 132358: ArcotId Certificate received with signature hav +e ArcotExtension. Cert issuer=CN= Fri May 29 18:31:53.498 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 170: 132358: ArcotID Auth SUCCESS (serial Number [e93b]) For Fail the line is -- Auth fail due to signature verification.Serial Number [11872] Fri May 29 18:31:53.498 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 170: 132358: Session tracker Id associated with verify signe +d challenge[11:132351] Fri May 29 18:31:53.498 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 17: 132358: ArAuthFrameworkImpl::doAuth::11:132351:: Authent +ication mechanism returned [0] for AuthIdentity [] Fri May 29 18:31:53.498 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 170: 132358: Handle_NSPAdvice:: Handling NSPAdvice for mecha +nism [4] Fri May 29 18:31:53.498 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 170: 132358: Handle_NSPAdvice::NSP Action :[NSP_RESET] Fri May 29 18:31:53.514 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 170: 132358: NSP Update Query is based on Serial Number Fri May 29 18:31:53.514 2009 Morocco Standard Time INFO: pid 3216 t +id 2888: 17: 132358: ArAuthFrameworkImpl::doPostAuth::11:132351:: Aut +hentication mechanism returned [0] for AuthIdentity [01302904]
Thanks NT

Replies are listed 'Best First'.
Re: Comma seperated output
by Corion (Patriarch) on Jun 15, 2009 at 09:36 UTC
    while(my $line = <$log>) { $n++; $line =~ tr/\r\n//d; if ($line =~ /^(.*)INFO:.*recvd AA_BIN_MSG_GET_WLT/) { $Time_Stamp = $1; while ( $line = <$log> ) { ... while ( $line = <$log> ) {

    This structure makes little sense to me. You read in a loop from $log, but then, you read in an inner loop, again from $log, and then you enter another nested loop to read until you are at the end of the file. Is this an error or do you have specific criteria why you want to read until the end of the file?

    I think this is a good time to step back and make a list of what the program should actually do, and then to rewrite that code completely, as the structure and intention of this code is quite unclear to me.

      while(my $line = <$log>) { $n++; $line =~ tr/\r\n//d; if ($line =~ /^(.*)INFO:.*recvd AA_BIN_MSG_GET_WLT/) { $Time_Stamp = $1; while ( $line = <$log> ) { ... while ( $line = <$log> ) {
      I wanted to combine the if statements but if will only select one not all, i want the value for all the variables and then print that values in comma seperated values. This happens quite a number of time in the logfile so wanted to loop through the log file. I have to capture these data in the log file. Arcotid Time Stamp, Username, Success, Failure, Error Code, Error Message In the log snippet the userID can be found in- Code Arcot Native Server: recvd AA_BIN_MSG_VER_CHG Cert Subject String....:CN=01095848;O=MLS; UserID=012345; CardName=ARCARD Success and failure are like this- Code ArcotID Auth SUCCESS (serial Number e93b) Auth fail due to signature verification.Serial Number 11872(This is error message also) Code error code is - Authentication mechanism returned 3, here 3 is error code and for success error code is always 0. Thanks NT

        From your description, I can't see a real list of things that the program should do, in order. I interpret your sentences as the following sequence of things to be done:

        1. Read through the file line by line
        2. Whenever there is a "value"
          1. Collect that "value".

        If my interpretation is wrong, please write your own list of what the program should do. Please try to structure that list like I did, by formatting it for example with <ol><li>... tags or <code> tags, so it becomes conveniently readable.

        If my interpretation of your description matches what you want, look at your code and determine where your code does not match the description and write new code that matches the description.

Re: Comma seperated output
by jethro (Monsignor) on Jun 15, 2009 at 10:07 UTC

    If those nested loops are there to read only the next line, use if ( $line = <$log>) { ... } else { last; } instead of your while

    if the line you are looking for might not be the next line but one of the next lines, then you have to use a while, but inside that while loop you need something to break that loop, like

    if ( found_what_I_was_looking_for ) { print the_information last; }

    Note that logfiles might have those additional lines intermixed with lines from other log events. If you want to catch that too, your program needs to remember unfinished events or cache new events until the unfinished event was processed

Re: Comma seperated output
by rovf (Priest) on Jun 15, 2009 at 10:25 UTC
    but the final outcome prints it only once

    Not sure if I understand your question correctly, but the logic of your program looks weird: Your program starts by reading some lines from your log (this is the outermost while. This goes on until it reads the first INFO line in the log. After this, the second while-statement starts reading lines from the log, until a line continuing AA_BIN_MSG_VER_CHG is found. Finally, the third while-statement reads all the remaining lines in the log. The last of those lines which happen to contain a User Id, set the variable $User_Id. The subsequent while loops are ignored, because you are already at EOF. Then comes one print statement. Then comes a next statement (which is superfuous anyway, because it is at the end of the loop). The enclosing while loop won't be entered again, since, as we saw, you are already at EOF. Hence all you see is just one diagnostic line printed.

    BTW, where is your use strict; use warnings;?

    -- 
    Ronald Fischer <ynnor@mm.st>