2010-11-12 29 views
2

我有多個數據結構中的一個文件它像這樣間檢查:用awk兩個日期

eventTimestamp: 2010-03-23T07:56:19.166 
result: Allowed 
protocol: SMS 
payload: RCOMM_SMS 

eventTimestamp: 2010-03-23T07:56:19.167 
result: Allowed 
protocol: SMS 
payload: RCOMM_SMS 

eventTimestamp: 2010-03-23T07:56:19.186 
result: Allowed 
protocol: SMS 
payload: SMS-MO-FSM 

eventTimestamp: 2010-03-23T07:56:19.197 
result: Allowed 
protocol: SMS 
payload: COPS 

eventTimestamp: 2010-03-23T07:56:29.519 
result: Blocked 
protocol: SMS 
payload: COPS 
type: URL_IWF 
result: Blocked 

我想找出所有有效載荷的事件:SMS-MO-FSM或有效載荷:發生在時間之間的SMS-MO-FSM-INFO 2010-03-23 12:56:47和2010-03-23 13:56:47。當查詢該文件到目前爲止,我還以下列方式使用AWK:

cat checkThis.txt | 
awk 'BEGIN{FS="\n"; RS=""; OFS=";"; ORS="\n"} 
    $1~/eventTimestamp: 2010-03-23T14\:16\:35/ && $4~/SMS-MO-FSM-INFO|SMS-MO-FSM$/ {$1=$1 ""; print $0}' 

哪位能給我的一切,對十四時16分35秒在2010-03-23第二次發生的事件。然而,我正在努力思考如何將日期範圍放入我的查詢中。我可以使用以下方法來把日期爲劃時代的時間,但我該如何使用我的AWK以下檢查日期是否之間所需的時間:

python -c "import time; ENGINE_TIME_FORMAT='%Y-%m-%dT%H:%M:%S'; print int(time.mktime(time.strptime('2010-03-23T12:52:52', ENGINE_TIME_FORMAT)))" 

我知道這可能在Python這樣做,但我有在Python中爲此編寫了一個解析器,並且我希望將此方法作爲替代檢查器,所以我想盡可能使用awk。

我把這個遠一點,創造一個Python腳本時間轉換:

#!/usr/local/bin/python 
import time, sys 
ENGINE_TIME_FORMAT='%Y-%m-%dT%H:%M:%S' 
testTime = sys.argv[1] 
try: 
    print int(time.mktime(time.strptime(testTime, ENGINE_TIME_FORMAT))) 
except: 
    print "Time to convert %s" % testTime 
    raise 

然後我試圖用函數getline分配轉換爲一個變量進行比較:

cat checkThis.txt| awk 'BEGIN {FS="\n"; RS=""; OFS=";"; ORS="\n"; "./firstDate '2010-03-23T12:56:47'" | getline start_time; close("firstDate"); "./firstDate '2010-03-23T13:56:47'" | getline end_time; close("firstDate");} ("./firstDate $1" | getline) > start_time {$1=$1 ""; print $0}' 
Traceback (most recent call last): 
    File "./firstDate", line 4, in <module> 
testTime = sys.argv[1] 
IndexError: list index out of range 

的getline在BEGIN中工作,我在最終的打印中檢查了它,但似乎在腳本的比較部分存在問題。

+0

你有'gawk'?它支持使用'mktime'將日期規範轉換爲時間戳(您可能需要稍微解析日期規格 - 將連字符,冒號和「T」轉換爲空格並刪除小數部分)。 – 2010-11-12 11:18:39

+0

我會如何使用gawk? – amadain 2010-11-12 11:37:59

+0

我嘗試使用awks getline來做時間轉換,但似乎無法在腳本的比較部分中使用它(請參閱除原始問題外)。我認爲同樣的問題會出現在gawk – amadain 2010-11-12 11:44:55

回答

6

關鍵的觀察是,你可以比較使用字母數字比較,您的時間戳和得到正確的答案 - 那就是ISO 8601符號的美感。

因此,適應你稍微代碼 - 和格式,以避免滾動條:

awk 'BEGIN { 
     FS = "\n" 
     RS = "" 
     OFS = ";" 
     ORS = "\n" 
     t1 = "2010-03-23T07:45:00" 
     t2 = "2010-03-23T08:00:00" 
     m1 = "eventTimestamp: " t1 
     m2 = "eventTimestamp: " t2 
     } 
$1 ~ /eventTimestamp:/ && $4 ~ /SMS-MO-FSM(-INFO)?$/ { 
    if ($1 >= m1 && $1 <= m2) print $1, $2, $3, $4; 
}' "[email protected]" 

很明顯,你可以把它變成腳本文件 - 你不希望經常鍵入它。準確方便地輸入日期範圍是其中的難點之一。請注意,我已調整時間範圍以符合數據。

當樣本數據運行時,它輸出一個記錄:

eventTimestamp: 2010-03-23T07:56:19.186;result: Allowed;protocol: SMS;payload: SMS-MO-FSM 
1

有點混亂,但是這個腳本假定你有unix「date」命令。還在BEGIN塊中硬編碼您的開始和結束時間戳。請注意,上面列出的測試數據不在您的示例開始/結束時間內。

#!/usr/bin/awk -f 
BEGIN { 
     command="date -f\"%s\" -d \"2010-03-23 12:56:47\""; command | getline startTime; close(command) 
     command="date -f\"%s\" -d \"2010-03-23 13:56:47\""; command | getline endTime; close(command) 
} 

$0 ~ /^eventTimestamp:/ { 
     command="date -f\"%s\" -d " $2; command | getline currTime; close(command) 

     if (currTime >= startTime && currTime <= endTime) { 
       printIt="true" 
     }else{ 
       printIt="false"; 
     } 
} 

printIt == "true" { print }    
+0

因爲我還沒有足夠的聲望投票,所以我不能爲Jonathan Leffler的解決方案投票。但它是一個很好的。 – cryptochaos 2010-11-13 05:01:12