2012-03-02 11 views
5

で、このより良い書き込む方法:私は時間あたりのエラーの数を見つけるためにしようとしています次のようになり、大きな入力ファイルを考えるとperlの

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 

。つまり、私はこのようになり、出力ファイルを探しています:私はこれができるかなり確信している、

#!/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"; 
} 

しかし、与えられたPerlの機能:ここで

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

することは私のために働いているスクリプトです。より少ない行で行うことができます。 いくつか例を挙げていただければ幸いです。私は、何かを達成するために書かれたコードの行を減らしたい人にとっては、役に立つと思います。

+2

'use strict; ' – Ether

+3

Perlではなく、' sed 's/:.*//' |警告を使用します。ユニーク-c' –

答えて

6

あなたの持っているものはすでにかなり短いです。字句ファイルハンドルを使用し、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 

それともあなたは本当にそれが短い場合は、どのように1つのライナーについて:

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

すっきり!誰も何も良いことを投稿しなければあなたの答えを受け入れるでしょう。 –

+3

'END'の代わりに、eskimo kiss演算子を使うことができます。 '} {言う...キー%t''。 – TLP

+2

これは良い/短く/より読みやすいのかどうかは分かりませんが、ここではコロンとeskimo演算子の自動分割を使用しています: 'perl -F:-lanwe '$ a {$ F [0]} ++; } {print "$ _ - > $ a {$ _}"キーは%a 'infile' – TLP

2

あなたが有効に活用することができますnamed capture groupsは、バージョン5.10以降の新機能で、あなたのパターンがあなたの意図をよりよく表現し、正しくソートされた出力を生成します。

数値を使用せずに名前付きキャプチャグループを作成することもできます。記法は(?<name>...)を宣言し、\g{name}を参照します。 (.NET正規表現と互換性があるためには\g{name}\k{name},\k<name>または\k'name'と書かれている可能性があります)は数字で始まりハイフンを含むことはできません。同じパターン内の異なるグループが同じ名前を持つ場合、その名前への参照は一番左に定義されたグループを想定します。名前付きグループは、絶対番号と相対番号でカウントされるため、これらの番号で参照することもできます。

キャプチャグループの内容は動的にスコープされ、囲みブロックの最後まで、または次の成功したマッチまで(どちらか早い方になるまで)、パターン外で利用できます最初。 (perlsynの複合文を参照してください。)絶対数で参照できます(\g1の代わりに$1などを使用します)。または%+ hashを介して$+{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
1

SUBSTRは、正規表現よりも効率的です。 CPANへのアクセス権がある場合、ソートはTie :: IxHashで取り除くことができます.Ty :: 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 

あなたはタイへのアクセス権を持っていない場合:: 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; 
関連する問題