2011-10-04 41 views
1
[2011-09-23 18:46:51:697 GMT+00:00][17B020C421B4BCC2CEBAD9C1B77CA413.http-8080-6][com.abc.actions.RegisterAction] INFO loggedOut #mouseclicked# userid=1 
[2011-09-24 19:46:53:697 GMT+00:00][47B020C421B4BCC2CEBAD9C1B77CA413.http-8080-6][com.abc.actions.RegisterAction] INFO loggedOut #mouseclicked# userid=12 
[2011-09-25 20:46:51:697 GMT+00:00][57B020C421B4BCC2CEBAD9C1B77CA413.http-8080-6][com.abc.actions.RegisterAction] INFO loggedin #mouseclicked# userid=23 
[2011-09-25 20:46:51:697 GMT+00:00][57B020C421B4BCC2CEBAD9C1B77CA413.http-8080-6][com.abc.actions.RegisterAction] DEBUG mouseclicked by userid=566 
[2011-09-25 20:56:56:697 GMT+00:00][77B020C421B4BCC2CEBAD9C1B77CA413.http-8080-6][com.abc.actions.RegisterAction] INFO loggedin #mouseclicked# userid=44 
[2011-09-26 22:48:55:697 GMT+00:00][87B020C421B4BCC2CEBAD9C1B77CA413.http-8080-6][com.abc.actions.RegisterAction] INFO loggedOut #mouseclicked# userid=55 

在上面的文件中,我想知道在從9月24日到11月25日(包括兩個日期)的日期範圍內發生了多少次#mouseclicked#。Unix grep查詢

在上述情況下,命令應返回我3(注:是的mouseClicked不考慮,因爲它不是以#匹配的mouseClicked#)

我怎麼能在這種情況下使用grep命令?

+0

grep的通過線工作線,所以日期限制是有點棘手。我猜,你可以grep for'mouseclicked'並將結果排序爲開頭,但是也許不同的工具會更有用(可能是Perl?)。 –

回答

3

grep孤單不會解決一般問題。它無法識別在特定日期範圍內的線條。 (嗯,這大概可以,如果你使用一個足夠複雜的正則表達式,但正則表達式將是約會,你有興趣的每個範圍完全不同。)

但是對於您的具體問題,這將工作:

egrep -c '^\[2011-09-(24|25).*#mouseclicked#' filename 

egrep支持更強大的正則表達式形式,包括|運算符。 -c選項告訴它打印匹配行的數量,而不是自己打印行。

但是,正如你可以想象的那樣,如果你想從9月30日下午1點到10月2日上午11點的線條,正則表達式會變得更加複雜,並且構建它需要一些重要的努力。

如果我打算做這個有很多,我會寫一個單獨的工具,它可以提取日期的指定範圍內的行(或日期和時間),同時在該文件中使用的特定日期格式的優勢( YYYY-MM-DD HH:MM:SS,ISO-8601是一個很好的選擇)。就我個人而言,我會用Perl編寫這樣一個工具。然後我可以在該文件上運行該工具並通過grep管道輸出。

編輯

在迴應評論,grep不明白日期範圍,只是字符序列。您可以編寫一個複雜的正則表達式,以匹配2010年10月1日至2011年1月1日範圍內的所有內容。這是我嘗試(未測試):

egrep -c '^\[(2010-1.*|2011-(0.|10|11)|2011-12-01).*#mouseclicked#' filename 

這涉及幾個單獨的子範圍:通過2010年1月的月,月到九月,那麼十月,那麼2011年11月,終於2011年

12月1日

而且,正如我上面所說的,任何其他日期範圍(或更糟的是,日期和時間),你需要構建符合所需的時間跨度子範圍的全新複雜的正則表達式的基礎上,他們的文字表述,而不是日期的含義。

這就是爲什麼我不會考慮這種方法,如果我想要做的不是一次或兩次,這更。

你知道像Perl或Python這樣的腳本語言嗎?如果是這樣,編寫一個實際上可以解析時間戳並選擇所需範圍內的行的腳本不會太困難。

事實上,如果這樣的工具已經存在(我只是不知道在哪裏可以找到它),我一點也不會感到驚訝。

編輯2

這裏是一個Perl腳本,我扔在一起:

#!/usr/bin/perl 

use strict; 
use warnings; 

die "Usage: $0 start end [file...]\n" if scalar @ARGV < 2; 
my $start = shift; 
my $end = shift; 
$start =~ s/\D//g; 
$end =~ s/\D//g; 
$end .= '99999999999999999999999999999'; 

print "start=\"$start\", end=\"$end\"\n"; 

while (<>) { 
    if (/^\[([^]]+)\]/) { 
     my $timestamp = $1; 
     $timestamp =~ s/\D//g; 
     if ($timestamp ge $start and $timestamp le $end) { 
      print; 
     } 
    } 
} 

它把指定的開始和結束時間,以及該文件中的時間戳,作爲數字序列和對它們進行一個字符串(非數字)比較。它忽略了時區信息。使用CPAN的時間和日期模塊可以使其更加複雜。

對於你原來的問題,你會運行:

this-perl-script 2011-09-24 2011-09-25 input-file | grep -c '#mouseclicked#' 
+0

如何使用上述命令給出日期範圍,例如從2010年10月1日至2011年1月1日? – Mike

0

我會嘗試類似 grep | wc -l

grep將過濾包含您的字符串的喜歡,而wc -l將計算grep輸出的行數。

+0

'grep -c'比較簡單。 –

1
cat filename | grep '^\[2011-09-2[45]' | grep mouseclicked | wc -l 

或者更簡單地說:

grep '^\[2011-09-2[45]' filename | grep -c mouseclicked 
+2

'cat'和'wc -l'都是不必要的。而且你需要逃避'['所以'grep'不認爲它是字符範圍的開始。 –

+0

同意!我沒有逃脫第一個'[':-)感謝輸入 – 2011-10-04 23:54:32

+0

不,你沒有逃脫第一個'[';我做到了。 –