2013-04-02 88 views
1

我正在嘗試在Python中執行以下操作,還使用了一些bash腳本。除非在Python中有更簡單的方法。Python腳本搜索並將結果導出到.csv文件

我有,看起來像數據的日誌文件中的以下內容:

16:14:59.027003 - WARN - Cancel Latency: 100ms - OrderId: 311yrsbj - On Venue: ABCD 
16:14:59.027010 - WARN - Ack Latency: 25ms - OrderId: 311yrsbl - On Venue: EFGH 
16:14:59.027201 - WARN - Ack Latency: 22ms - OrderId: 311yrsbn - On Venue: IJKL 
16:14:59.027235 - WARN - Cancel Latency: 137ms - OrderId: 311yrsbp - On Venue: MNOP 
16:14:59.027256 - WARN - Cancel Latency: 220ms - OrderId: 311yrsbr - On Venue: QRST 
16:14:59.027293 - WARN - Ack Latency: 142ms - OrderId: 311yrsbt - On Venue: UVWX 
16:14:59.027329 - WARN - Cancel Latency: 134ms - OrderId: 311yrsbv - On Venue: YZ 
16:14:59.027359 - WARN - Ack Latency: 75ms - OrderId: 311yrsbx - On Venue: ABCD 
16:14:59.027401 - WARN - Cancel Latency: 66ms - OrderId: 311yrsbz - On Venue: ABCD 
16:14:59.027426 - WARN - Cancel Latency: 212ms - OrderId: 311yrsc1 - On Venue: EFGH 
16:14:59.027470 - WARN - Cancel Latency: 89ms - OrderId: 311yrsf7 - On Venue: IJKL 
16:14:59.027495 - WARN - Cancel Latency: 97ms - OrderId: 311yrsay - On Venue: IJKL 

我需要提取每行的最後一個條目,然後使用每個獨特的條目,搜索每一行,它出現在並將其導出到.csv文件。

我已使用以下bash腳本來獲取每個唯一條目: cat LogFile_ date +%Y%m%d .msg.log | awk'{print $ 14}'|排序| uniq的

基於日誌文件上面的數據中,bash腳本將返回以下結果:

ABCD 
EFGH 
IJKL 
MNOP 
QRST 
UVWX 
YZ 

現在我想搜索(或grep)來爲每個結果在相同的日誌文件並返回前十個結果。我有另一個bash腳本來做到這一點,但是,我怎麼做這個使用循環?因此,對於x,其中x =上面的每個條目,

grep x LogFile_ date +%Y%m%d .msg.log | awk'{print $ 7}'| sort -nr | uniq |頭-10

然後將結果返回到.csv文件。結果是這樣(每個字段在單獨的列):

Column-A Column-B Column-C Column-D 
ABCD  2sxrb6ab Cancel 46ms 
ABCD  2sxrb6af Cancel 45ms 
ABCD  2sxrb6i2 Cancel 63ms 
ABCD  2sxrb6i3 Cancel 103ms 
EFGH  2sxrb6i4 Cancel 60ms 
EFGH  2sxrb6i7 Cancel 60ms 
IJKL  2sxrb6ie Ack  74ms 
IJKL  2sxrb6if Ack  74ms 
IJKL  2sxrb76s Cancel 46ms 
MNOP  vcxrqrs5 Cancel 7651ms 

我在Python初學者,因爲大學裏沒有做什麼編碼(13年前)。任何幫助將不勝感激。謝謝。

+0

您的輸出如何與您的輸入相對應? –

回答

1

假設你已經打開你的文件。你想要做的是記錄每個單獨條目多少次是在那裏,這是說,每個條目將導致一個或多個計時:

from collections import defaultdict 

entries = defaultdict(list) 
for line in your_file: 
    # Parse the line and return the 'ABCD' part and time 
    column_a, timing = parse(line) 
    entries[column_a].append(timing) 

當你完成後,你有一個像字典所以:

{ 'ABCD': ['30ms', '25ms', '12ms'], 
    'EFGH': ['12ms'], 
    'IJKL': ['2ms', '14ms'] } 

什麼你會想現在要做的就是改造這個字典到由它的價值len(這是一個列表)訂購了數據結構。例如:

In [15]: sorted(((k, v) for k, v in entries.items()), 
       key=lambda i: len(i[1]), reverse=True) 
Out[15]: 
[('ABCD', ['30ms', '25ms', '12ms']), 
('IJKL', ['2ms', '14ms']), 
('EFGH', ['12ms'])] 

當然,這僅是說明性的,你可能想收集更多的數據在原來for循環。

0

也許不是不簡潔,你可能會想......但我認爲這可以解決你的問題。我添加一些try ... catch來更好地處理真實數據。

import re 
import os 
import csv 
import collections 

# get all logfiles under current directory of course this pattern can be more 
# sophisticated, but it's not our attention here, isn't it? 
log_pattern = re.compile(r"LogFile_date[0-9]{8}.msg.log") 
logfiles = [f for f in os.listdir('./') if log_pattern.match(f)] 

# top n 
nhead = 10 
# used to parse useful fields 
extract_pattern = re.compile(
    r'.*Cancel Latency: ([0-9]+ms) - OrderId: ([0-9a-z]+) - On Venue: ([A-Z]+)') 
# container for final results 
res = collections.defaultdict(list) 

# parse out all interesting fields 
for logfile in logfiles: 
    with open(logfile, 'r') as logf: 
     for line in logf: 
      try: # in case of blank line or line with no such fields. 
       latency, orderid, venue = extract_pattern.match(line).groups() 
      except AttributeError: 
       continue 
      res[venue].append((orderid, latency)) 

# write to csv 
with open('res.csv', 'w') as resf: 
    resc = csv.writer(resf, delimiter=' ') 
    for venue in sorted(res.iterkeys()): # sort by Venue 
     entries = res[venue] 
     entries.sort() # sort by OrderId 
     for i in range(0, nhead): 
      try: 
       resc.writerow([venue, entries[i][0], 'Cancel ' + entries[i][1]]) 
      except IndexError: # nhead can not be satisfied 
       break 
+0

可能是簡單的東西,但我得到的錯誤:打開(日誌文件,'r')作爲logf: ^ SyntaxError:無效的語法 – user2234571

+0

謝謝弗朗西斯陳的幫助。這很好。有沒有辦法將每個字段寫入.csv文件中的單獨列,每列都有相應的標題?現在寫它將所有4個字段寫入同一列(列A)。另外,我希望按照Venue的字母順序進行排序,然後按第4場降序排列(63ms,64ms,63ms,62ms ...等)?再次感謝您的幫助。 – user2234571

+0

另外,我應該使用我的日誌文件的更好的例子。有兩種不同類型的「延遲」,但我只顯示了一種類型,即「取消」。它實際上是「取消」或「確認」。如何在延遲之前包含正確的前面的單詞? 16:14:59.027010 - WARN - 取消延遲:22ms - 訂單ID:311yrsbl - 開啓地點:EFGH 16:14:59.027201 - WARN - 確認延遲時間:22ms - 訂單ID:311yrsbj - WARN - 確認延遲:22ms - 訂單ID:311yrsbn - 開啓地點:IJKL 16:14:59.027235 - WARN - 取消延遲:22ms - 訂單ID:311yrsbp - 開啓地點:MNOP – user2234571