How to write it better in perl

Given a large input file that looks like this:

02/26/2012 08:54:38 Error:java.sql.Exception
02/26/2012 08:54:48 Error:java.sql.Exception
02/26/2012 08:56:05 Error:java.sql.Exception
02/26/2012 08:57:21 Error:java.sql.Exception
02/26/2012 08:59:29 Error:java.sql.Exception
02/26/2012 09:01:14 Error:java.sql.Exception
02/26/2012 09:08:48 Error:java.sql.Exception
02/26/2012 09:10:41 Error:java.sql.Exception

I am trying to figure out the number of errors per hour; that is, I am looking for an output file that looks like this:

02/26/2012 08 -> 5
02/26/2012 09 -> 3

Here is a script that works for me:

#!/bin/perl
open(MYFILE, 'tata2');
my %table;
while (<MYFILE>) {
     chomp;
     $dtkey = substr $_, 0, 13;
     $table{$dtkey}++;
}
close(MYFILE); 
for my $key (keys %table) {
    print "$key -> $table{$key}\n";
}

But given the Perls functions, I'm sure this can be done in fewer lines. Identification is much appreciated if you can give a few examples. I hope this will be useful for those who want to reduce the number of lines of code written to achieve something.

+5
source share
3 answers

You are already pretty short. You can improve the situation a bit by using lexical file descriptors and checking the return value of open.

Perl:

open my $fh, '<', 'filename' or die $!;
my %table;

while (<$fh>) {
    $table{$1}++ if /([^:]+)/ # regex is a bit shorter than the substr
}

print "$_ -> $table{$_}\n" for keys %table;  # statement modifier form

, , :

perl -lnE '$t{$1}++ if /([^:]+)/; END {say "$_ -> $t{$_}" for keys %t}' infile
+6

, 5.10, .

. (?<name>...) \g{name} . ( .NET, \g{name} \k{name}, \k<name> \k'name'.) . , . , . ( , (??{}).)

, , . (. perlsyn.) ( $1 \g1 ..); %+ , $+{name}.

, YYYY/MM/DD HH .

#! /usr/bin/env perl

use strict;
use warnings;

use 5.10.0;  # named capture buffers

*ARGV = *DATA;  # for demo only; remove for real use

my %hour_errors;
while (<>) {
  $hour_errors{"$+{y}/$+{m}/$+{d} $+{h}"}++
    if m!^ (?<m> \d+) / (?<d> \d+) / (?<y> \d+)  \s+  (?<h> \d+) :!x;
}

print "$_ -> $hour_errors{$_}\n" for sort keys %hour_errors;

__DATA__
02/26/2012 08:54:38 Error:java.sql.Exception
02/26/2012 08:54:48 Error:java.sql.Exception
02/26/2012 08:56:05 Error:java.sql.Exception
02/26/2012 08:57:21 Error:java.sql.Exception
02/26/2012 08:59:29 Error:java.sql.Exception
02/26/2012 09:01:14 Error:java.sql.Exception
02/26/2012 09:08:48 Error:java.sql.Exception
02/26/2012 09:10:41 Error:java.sql.Exception

:

2012/02/26 08 -> 5
2012/02/26 09 -> 3
+2

Substr , , . CPAN, Tie:: IxHash, ( ). ( , .)

use Tie::IxHash;
tie my %table, 'Tie::IxHash';
$table{substr $_, 0, 13}++ while <DATA>;
print "$_ -> $table{$_}\n" for keys %table;
__DATA__
02/26/2012 09:10:41 Error:java.sql.Exception
02/26/2012 08:54:38 Error:java.sql.Exception
02/26/2012 08:54:48 Error:java.sql.Exception
02/26/2012 08:56:05 Error:java.sql.Exception
02/26/2012 08:57:21 Error:java.sql.Exception
02/26/2012 08:59:29 Error:java.sql.Exception
02/26/2012 09:01:14 Error:java.sql.Exception
02/26/2012 09:08:48 Error:java.sql.Exception
02/26/2012 09:10:41 Error:java.sql.Exception
03/26/2012 08:54:38 Error:java.sql.Exception
03/26/2012 08:54:48 Error:java.sql.Exception
03/26/2012 08:56:05 Error:java.sql.Exception
03/26/2012 08:57:21 Error:java.sql.Exception
03/26/2012 08:59:29 Error:java.sql.Exception
03/26/2012 09:01:14 Error:java.sql.Exception
03/26/2012 09:08:48 Error:java.sql.Exception
04/26/2012 08:54:38 Error:java.sql.Exception
04/26/2012 08:54:48 Error:java.sql.Exception
04/26/2012 08:56:05 Error:java.sql.Exception
04/26/2012 08:57:21 Error:java.sql.Exception
04/26/2012 08:59:29 Error:java.sql.Exception
04/26/2012 09:01:14 Error:java.sql.Exception
04/26/2012 09:08:48 Error:java.sql.Exception
04/26/2012 09:10:41 Error:java.sql.Exception

Tie:: IxHash, ( DATA).

my %table;
$table{substr $_, 0, 13}++ while <DATA>;
print "$_ -> $table{$_}\n" for sort { "@{[($a=~/(\d+)\D?/g)[2,1,0,3]]}" cmp "@{[($b=~/(\d+)\D?/g)[2,1,0,3]]}" } keys %table;
+1
source

All Articles