http://www.perlmonks.org?node_id=731749

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


I am having one requirement.
my input format is like this.

month-date hh:mm:ss tid1 start trname tramount
month-date hh:mm:ss tid2 start trname tramount
month-date hh:mm:ss tid1 stop
month-date hh:mm:ss tid3 start trname tramount
month-date hh:mm:ss tid2 stop
month-date hh:mm:ss tid3 stop
month-date hh:mm:ss tid4 start trname tramount

where tid is transaction id, trname is transaction name and tramount is transaction amount.

I want the output - transaction id, transaction name, transaction amount and duration of the transaction ( diff between start time and end time).

One more in the report, if the transaction is started but not stopped, that also should get highlighted in the output

To do this I have done the coding, and it is working for me

Input:
12-20 12:10:06 12 start idbi 1000
12-20 12:11:23 16 start hdfc 2000
12-20 14:03:24 12 stop
12-20 14:45:53 18 start icici 2018
12-20 15:12:32 16 stop
12-20 15:45:60 18 stop
12-20 16:00:03 112 start universal 3400
Output:
Transaction id 12 name idbi Amount 1000 Duration 1:53:18
Transaction id 16 name hdfc Amount 2000 Duration 3:1:9
Transaction id 18 name icici Amount 2018 Duration 1:0:7
============================================
Transaction with id 112 is started but not yet stopped

My code is here:
$File = "input.txt"; open(FH,$File); while ( <FH>) { ## Chomp the read line. i.e removing \n available at the end chomp; ## taking time, transaction id, status, transaction name and amou +nt. if ( $_ =~ /([0-9]+\:[0-9]+\:[0-9]+) ([0-9]+) (\w+) (\w+) (\w+)/ ) +{ $time = $1; $tid = $2; $status = $3; $trname = $4; $tramount = $5; $hash{$2}->[0] = $status; $hash{$2}->[1] = $time; $hash{$2}->[2] = $trname; $hash{$2}->[3] = $tramount; } ## If the status is stop.. elsif ( $_ =~ /([0-9]+\:[0-9]+\:[0-9]+) ([0-9]+) (\w)/ ) { $status = $3; $hash{$2}->[0] = $status; $difftime = find_diff($hash{$2}->[1],$1); $hash{$2}->[1] = $difftime; print "Transaction id $2 name ".$hash{$2}->[2]." Amount ". $ha +sh{$2}->[3]." Duration ".$hash{$2}->[1]."\n"; # If the transaction is stopped initialising the values. $hash{$2}->[0] = 0; $hash{$2}->[1] = 0; $hash{$2}->[2] = 0; $hash{$2}->[3] = 0; } } print "============================================\n"; ## to print the transaction started but not yet stopped foreach $id ( keys %hash ) { if ( $hash{$id}->[0] =~ /start/i ) { print "Transaction with id $id is started but not yet stop +ped\n"; } } sub find_diff { ## Get the start time and end time and store that in a variable. my ( $begin, $end ) = @_; # Declaration of local variables. my ( $hour , $min, $sec , $hour1, $min1, $sec1, $tdiff); # split the start time which has a : as a seperator, and store hou +r, min # sec. ($hour, $min, $sec ) = split(/\:/,$begin); # Convert the start time into seconds. $stime = ( $hour *3600 ) + ($min *60) + $sec; # split the end time which has a : as a seperator, and store hour, + min # sec. ($hour1, $min1, $sec1 ) = split(/\:/,$end); # Convert the end time into seconds. $etime = ( $hour1 *3600 ) + ($min1 *60) + $sec1; # subtract the end time from start time. $diff = $etime - $stime; # conversion of seconds to hour, min and sec. $hour = int($diff/3600); $min1 = int($diff%3600); $min = int($min1/60); $sec = int($min1%60);# Form the hour min sec like hh:mm:ss $tdiff = $hour.":".$min.":".$sec; # return the output. return $tdiff; }

Kindly advice some efficient and short method for this.