2013-04-02 41 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