2012-12-19 21 views
6

如何使用時間戳記計數grep如何使用時間戳記做grep計數

例如:如果我有一個文件,每次搜索一個值xyz。該文件定期更新。

20121912-07:15:55 abc cbfr xyz 
20121912-07:16:40 mni cbfr xyz 
----------- 
----------- 
----------- 


20121912-08:15:55 gty cbfr xyz 
20121912-08:20:55 jui uio xyz 

我想20121912-08:15:55在這種情況下應該是2後,找出xyz的出現次數。

做一個grep -c "xyz" filename讀取整個文件並給出結果。我想在最後一次更新之後或使用時間戳。

+3

的時間戳格式不幸的選擇。 –

回答

1

這是怎樣的一個黑客攻擊的只是grep對於使用-A然後通過管道之後的所有行,你想要的最早日期和打印到grep -c xyz

$ fgrep -A 100 '20121912-08:15:55' file | fgrep -c 'xyz' 
2 

注:fgrep只是固定字符串grep你'不使用regex模式,它與grep -F一樣。

由於少哈克的方式是使用sed打印之日起的所有行,這樣你就不會需要確保價值-A將覆蓋該文件的長度:

$ sed -n '/20121912-08:15:55/,$p' file | fgrep -c 'xyz' 
2 

這是假設,當然你的文件是有序的時間戳,如果它不是那麼:

$ sort file | sed -n '/20121912-08:15:55/,$p' | fgrep -c 'xyz' 
2 
+0

3個問題:a,如果文件沒有按時間戳排序會發生什麼? b,20121912-08開始的線路如何:10:10? c,如果20121912-08行後有多少行? – Kent

+0

現在回答所有這些問題。 –

2

嘗試這一個班輪:

awk '$NF=="xyz"&&$1>="20121912-08:15:55"{x++;}END{print x}' file 
+0

不知道awk會解析和比較時間戳;非常整潔! – Rubens

+0

日期不按字典順序降序排列,例如2012年12月08日:15:55比「2012年12月12日:15:55」「更大」。 – Thor

+0

它工作嗎?我認爲awk解析時間戳D: – Rubens

1

您可以告訴sed從給定範圍(開始點和停止點)的文件中打印行 - 範圍可以是正則表達式或行號表示法。

您的需求,這應該這樣做:

$ sed -n '/20121912-08:15:55/,$p' input.txt | grep -c xyz 

這裏起點是日期給出,爲正則表達式處理,終點是最後一行符號$p告訴sed在給定的範圍內打印行。 sed的-n選項告訴它不打印它正在處理的行。

0

嗯,趕緊寫一個:

grep xyz filename | sed -r 's/^([^ ]+).*/ 20121912-08:15:55 <= \1/' | sed -r 's/([0-9]{4})([0-9]{2})([0-9]{2})/\1\3\2/g' | sed 's/[-:]//g' | bc | grep 1 | wc -l 

這是非常醜陋(我不是一個SED也沒有命令行主),並可以或許被縮短,但它是一個辦法做到這一點。下面說明:

grep xyz filename         //gets all interseting lines 
| sed -r 's/^([^ ]+).*/ 20121912-08:15:55 <= \1/' //transform them into 
                 //comparison with the 
                 //date you want 
| sed -r 's/([0-9]{4})([0-9]{2})([0-9]{2})/\1\3\2/g' //invert day and month 
| sed 's/[-:]//g'         //remove separators 
| bc             //ask bc result 
| grep 1            //get true results only 
| wc -l            //and finally count them 

對於示例的最後一行,步驟將使:

20121912-08:20:55 jui uio xyz     //grep 'xyz' 
20121912-08:15:55 <= 20121912-08:20:55   //sed 
20121219-08:15:55 <= 20121219-08:20:55   
20121219081555 <= 20121219082055    
1            //result from bc 

HTH

+1

在解釋時,遞減計數是好的...? – psycho

1

來自肯特的答案獲得靈感,這裏的一些Perl的操縱奇時間戳到年月日格式:

ts="20121912-08:15:55" patt="xyz" perl -lane ' 
    BEGIN { 
     ($wanted_ts = $ENV{ts}) =~ s/^(....)(..)(..)/$1$3$2/; 
     $pattern = qr{$ENV{patt}}; 
    } 
    ($this_ts = $F[0]) =~ s/^(....)(..)(..)/$1$3$2/; 
    $count++ if $this_ts ge $wanted_ts and /$pattern/; 
    END {print $count} 
' 
1

我假設你想找到位模式的特徵:'xyz',其中日期/時間值大於或等於指定的日期/時間:'20121912-08:15:55'。以下是我將要使用的GNU awk。運行,如:中script.awk

awk -v pattern="xyz" -v time="20121912-08:15:55" -f script.awk file 

內容:

BEGIN { 
    stamp = convert(time) 
} 

$0 ~ pattern && convert($1) >= stamp { 
    i++ 
} 

END { 
    print i 
} 

function convert(var) { 

    x = "(....)(..)(..)-(..):(..):(..)" 
    y = "\\1 \\3 \\2 \\4 \\5 \\6" 

    return mktime(gensub(x,y,"",var)) 
} 

結果:

2 

另外,這裏是一個班輪:

awk -v pattern="xyz" -v time="20121912-08:15:55" 'BEGIN { stamp = convert(time) } $0 ~ pattern && convert($1) >= stamp { i++ } END { print i } function convert(var) { return mktime(gensub(/(....)(..)(..)-(..):(..):(..)/,"\\1 \\3 \\2 \\4 \\5 \\6","",var)) }' file