赞
踩
项目中经常遇到一些简单但是重复性强的工作,比如确认log中是否报了一些有风险的warning。我通常是用搜索关键字的方法或者grep命令找我关注的warning,但是效率低且不能保证全面。如果有一个自动查找的脚本就好了,这篇博文记录如何在多个文档中一次查找多个关键词。
以前做项目的时候遇到过类似的问题,参考之前的解决方案:Python学习之re.compile与findall即可实现多个关键字的依次查找。总结下来就是两个关键点:
re.compile()
正则表达式匹配serach()
搜索文件内容import re # warning key_wds that we cares key_warn_lst = ['WARNING1', 'WARNING2', 'WARNING3', 'WARNING4'] def filter_key_wds(file_dir) key_warn_num_lst = [] with open(file_dir, 'r') as f_in: file_ctxt = f_in.read() # extract statistical warnings part warn_part = re.search(r'\d+ warnings[(](.*?)[)]', file_ctxt, re.S).group() # search key_warns we cares among warning parts for each_warn in key_warn_lst: key_warn_regex = '(?<=' + each_warn + ' : )\d+' key_warn_patte = re.compile(key_warn_regex) key_warn_num = key_warn_patte.search(warn_part) if key_warn_num: key_warn_num_str = key_warn_num.group() else: key_warn_num_str = '0' key_warn_num_lst.append(int(key_warn_num_str)) return key_warn_num_lst
\d+
表示匹配任意十进制数字1次或多次;[(]
表示匹配左圆括号;.*?
表示匹配任意长度、任意内容但不包括换行符
.
匹配除了换行符以外的任何字符,如果有re.S/re.DOTALL
标志则包括换行符*
匹配前面的字符0次或多次?
匹配前面的字符0次或1次+
匹配前面的字符1次或多次(see more regex in link)aaa(.*?)bbb
返回的结果不包括前后的aaa和bbbWARNING1
关键字,(?<=WARNING1 : )\d+
表示匹配“WARNING1+冒号+1或多个十进制数字”的字符串,但是匹配的结果不包括“WARNING1+冒号”,只返回数字
(?<=start_string)other_intended_string
other_intened_string(?=end_string)
import os
def check_files(dir_path, obj_file_lst):
warn_num_dict = {}
if os.path.isdir(dir_path):
file_lst = os.listdir(dir_path)
for file_name in file_list:
for obj_file_str in obj_file_lst:
if file_name.endswith(obj_file_str + 'warn.log'):
warn_num_dict[obj_file_str] = filter_key_wds(dir_path + '/' + file_name)
print(':) +++++ ' + filename + ' filtering is DONE. +++++')
else:
print(':( +++++'+ dir_path 'is invaild directory, please CHECK! +++++')
return warn_num_dict
os.path.isdir(path_string)
判断指定路径是否为目录;os.path.isfile(path_string)
判断指定路径是否为文件os.listdir(path_string)
返回一个指定路径下的所有文件、文件夹名称组成的列表warn_num_dict={}
表示这是个字典,以obj_file_str作为key、filter_key_wds返回的列表作为valuedef merge_result(key_warn_lst, wran_num_dict):
warn_num_lst_2d = []
for key in warn_num_dict:
warn_num_lst_tmp = warn_num_dict[key]
warn_num_lst_tmp.insert(0, key)
warn_num_lst_2d.append(warn_num_lst_tmp)
# multi-demontional list trnspose 多维列表转置
warn_num_lst = list(map(list, zip(*warn_num_lst_2d)))
# insert element at the beginning of list
key_warn_lst.insert(0, 'stage')
# combine two list as one tuple
key_warn_tpl = zip(key_warn_lst, warn_num_lst)
return key_warn_tpl
list_exmp.insert(0, new_element)
,列表结尾插入元素用list_exmp.append(new_element)
zip(iterable, ...)
函数将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,返回由这些元组组成的列表。参考linkmap(function, iterable, ...)
函数以参数序列iterable中的每个元素调用function函数,返回一个包含每次函数调用返回值的新列表。参考linkif __name__ == "__main__":
log_dir = '/data/project1/log'
my_file_lst = ['stage1', 'stage2']
warn_num_dict = check_files(log_dir, my_file_lst)
flt_warn_tpl = merge_result(key_warn_lst, wran_num_dict)
with open('flt_warn.txt','w') as f_out:
f_out.write('\n'.join('%-10s\t: %-10s' % x for x in flt_warn_tpl))
print('All fitering is DONE.')
%s
常用于输出格式的限定,将输出对象传递到str()
函数中,输出字符串%-10s
表示输出的字符串宽度为10个字符,宽度不足10则在右边补齐空格(即左对齐),超过10则按原长度输出%+10s
与上面类似,区别是宽度不足10时在左右边补齐空格(即右对齐)symbol.join(seq)
方法用于将序列seq中的元素以指定的字符symbol连接生成一个新的字符串Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。