Jun*_*ior 0 python regex logging filtering
大家早上好,想知道你是否可以帮助我解决以下问题: - 上周末我的一位同事向我展示了如何通过重新编写Bash脚本来大幅减少执行Bash脚本所需的时间蟒蛇.我对它跑得多快感到惊讶.我现在想用另一个脚本做同样的事情.
此其他脚本读取日志文件并使用AWK从日志中过滤某些字段并将其写入新文件.请参阅下面的脚本正在执行的正则表达式.我想在Python中重写这个正则表达式,因为我的脚本目前需要大约1个小时来执行大约100,000行的日志文件.我想尽可能减少这段时间.
cat logs/pdu_log_fe.log | awk -F\- '{print $1,$NF}' | awk -F\. '{print $1,$NF}' | awk '{print $1,$4,$5}' | sort | uniq | while read service command status; do echo "Service: $service, Command: $command, Status: $status, Occurrences: `grep $service logs/pdu_log_fe.log | grep $command | grep $status | wc -l | awk '{ print $1 }'`" >> logs/pdu_log_fe_clean.log; done
Run Code Online (Sandbox Code Playgroud)
这个AWK命令获得如下所示的行: -
2011-05-16 09:46:22,361 [Thread-4847133] PDU D <G_CC_SMS_SERVICE_51408_656.O_ CC_SMS_SERVICE_51408_656-ServerThread-VASPSessionThread-7ee35fb0-7e87-11e0-a2da-00238bce423b-TRX - 2011-05-16 09:46:22 - OUT - (submit_resp: (pdu: L: 53 ID: 80000004 Status: 0 SN: 25866) 98053090-7f90-11e0-a2da-00238bce423b (opt: ) ) >
Run Code Online (Sandbox Code Playgroud)
并输出这样的行: -
CC_SMS_SERVICE_51408 submit_resp:0
我自己尝试编写Python脚本但是我正在编写正则表达式.到目前为止,我有以下内容: -
#!/usr/bin/python
# Import RegEx module
import re as regex
# Log file to work on
filetoread = open('/tmp/ pdu_log.log', "r")
# File to write output to
filetowrite = file('/tmp/ pdu_log_clean.log', "w")
# Perform filtering in the log file
linetoread = filetoread.readlines()
for line in linetoread:
filter0 = regex.sub(r"<G_","",line)
filter1 = regex.sub(r"\."," ",filter0)
# Write new log file
filetowrite.write(filter1)
filetowrite.close()
# Read new log and get required fields from it
filtered_log = open('/tmp/ pdu_log_clean.log', "r")
filtered_line = filtered_log.readlines()
for line in filtered_line:
token = line.split(" ")
print token[0], token[1], token[5], token[13], token[20]
print "Done"
Run Code Online (Sandbox Code Playgroud)
丑陋我知道,但请记住,我刚刚开始学习Python两天前.
我一直在寻找这个群体,并在互联网上查找我可以使用的代码片段,但到目前为止,我发现的东西不符合我的需要或太复杂(至少对我而言).
任何建议,你可以给我如何完成这项任务的建议将不胜感激.
另外,你还可以推荐一本好的严肃书来学习Python吗?我读过Swaroop CH的"A Byte of Python"这本书(很棒的入门书!),我现在正在阅读Mark Pilgrim的"Dive into Python".我正在寻找一本用简单的术语解释事物并直截了当的书(类似于"Python的一个字节"的写法)
提前致谢
亲切的问候,
初级
=====回答以下评论的Eli =====
我道歉的人,我试着评论Eli的答案,但我的评论太长了,也无法保存.我也试过回答我自己的帖子,但由于我是新用户,我不能回答,直到8小时后!所以我唯一的选择是在我的帖子中添加一个编辑:)
无论如何,回应Eli的评论: -
好吧,让我们看看,我的目标是从日志文件中过滤掉几个字段并将它们写入新的日志文件.正如我之前提到的,当前的日志文件有如下数千行: -
2011-05-16 09:46:22,361 [Thread-4847133] PDU D.
日志文件中的所有行都相似,它们都具有相同的长度(相同的字段数).大多数字段用空格分隔,除了我用AWK处理的几个字段(删除"
我希望现在更清楚了
问候,
初级
由于这些线条非常结构化,为了简单(和速度),我根本不会使用正则表达式.这是一个提取您的第一个数据的示例:
>>> line = "2011-05-16 09:46:22,361 [Thread-4847133] PDU D <G_CC_SMS_SERVICE_51408_656.O_ CC_SMS_SERVICE_51408_656-ServerThread-VASPSessionThread-7ee35fb0-7e87-11e0-a2da-00238bce423b-TRX - 2011-05-16 09:46:22 - OUT - (submit_resp: (pdu: L: 53 ID: 80000004 Status: 0 SN: 25866) 98053090-7f90-11e0-a2da-00238bce423b (opt: ) ) >"
>>> istart = line.find('<G_')
>>> iend = line.find('.', istart)
>>> line[istart+3:iend]
'CC_SMS_SERVICE_51408_656'
Run Code Online (Sandbox Code Playgroud)
其他字段可以类似地提取,具体取决于所有可能行的确切结构.很难理解你的AWK究竟做了什么以及它如何应用于你提供的示例.如果您能够描述数据线的结构以及您需要提取的内容将会更容易.
例如,按照split您获得的空格(默认值)拆分该行:
>>> line.split()
['2011-05-16', '09:46:22,361', '[Thread-4847133]', 'PDU', 'D', '<G_CC_SMS_SERVICE_51408_656.O_', 'CC_SMS_SERVICE_51408_656-ServerThread-VASPSessionThread-7ee35fb0-7e87-11e0-a2da-00238bce423b-TRX', '-', '2011-05-16', '09:46:22', '-', 'OUT', '-', '(submit_resp:', '(pdu:', 'L:', '53', 'ID:', '80000004', 'Status:', '0', 'SN:', '25866)', '98053090-7f90-11e0-a2da-00238bce423b', '(opt:', ')', ')', '>']
Run Code Online (Sandbox Code Playgroud)
现在你几乎可以自由地从这里提取你需要的任何字段,只要(如你所说)格式是非常固定的,它总是相同的字段.所以:
>>> line.split()[13]
'(submit_resp:'
Run Code Online (Sandbox Code Playgroud)
清理一下:
>>> line.split()[13].lstrip('(').rstrip(':')
'submit_resp'
Run Code Online (Sandbox Code Playgroud)
如您所见,可能性是无限的.我建议你在熟悉正则表达式之前熟悉Python的字符串处理功能.正则表达式很有用,但它们并不是这项工作的唯一工具.通常,基于替代字符串处理技术的解决方案更快更容易理解.当然,你总能用正则表达式来补充它们.
PS关于学习Python的书籍/资源 - 关于这一点有很多SO问题.从这里开始浏览.