python学习之在多个文件中依次查找多个关键词

该文章介绍了如何利用Python编写脚本,通过正则表达式re.compile和findall方法,实现对多个文档中多个警告关键词的高效查找。脚本可以处理单个文件以及整个目录下的多个文件,最后将结果整合并写入文件,提高了日志分析的效率。
摘要由CSDN通过智能技术生成

项目中经常遇到一些简单但是重复性强的工作,比如确认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和bbb
  • 如果当前查找的是WARNING1关键字,(?<=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返回的列表作为value

整理多个文件的查找结果

def 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, ...)函数将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,返回由这些元组组成的列表。参考link
  • map(function, iterable, ...)函数以参数序列iterable中的每个元素调用function函数,返回一个包含每次函数调用返回值的新列表。参考link

主函数中将结果写入文件

if __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连接生成一个新的字符串
### 回答1: 如果要判断一个变量是否包含多个字符串,可以使用 Python 的 `in` 运算符。例如: ``` string = "abcdefg" if "a" in string and "b" in string and "c" in string: print("字符串 string 包含 a、b 和 c") else: print("字符串 string 不包含 a、b 和 c") ``` 上面的代码会判断字符串 `string` 是否包含字符串 `"a"`、`"b"` 和 `"c"`,如果都包含,则会输出 "字符串 string 包含 a、b 和 c",否则会输出 "字符串 string 不包含 a、b 和 c"。 你也可以将多个要判断的字符串放在一个列表,然后使用列表推导式来简化代码: ``` string = "abcdefg" strings = ["a", "b", "c"] if all(s in string for s in strings): print("字符串 string 包含所有的字符串") else: print("字符串 string 不包含所有的字符串") ``` 上面的代码会判断字符串 `string` 是否包含列表 `strings` 的所有字符串,如果都包含,则会输出 "字符串 string 包含所有的字符串",否则会输出 "字符串 string 不包含所有的字符串"。 注意:`in` 运算符是区分大小写的,因此 "A" 和 "a" 被视为不同的字符串。如果你想忽略大小写,可以先将所有的字符串都转 ### 回答2: 在Python,可以使用if语句来判断多个字符串是否在一个变量。具体步骤如下: 1. 首先,声明一个包含多个字符串的变量,可以使用列表或元组等数据结构来存储这些字符串。 2. 接下来,在if语句使用in关键字来判断每个字符串是否在这个变量。例如: ```python fruits = ['apple', 'banana', 'orange'] if 'apple' in fruits: print("苹果在水果列表") if 'pear' in fruits: print("梨子在水果列表") ``` 上述代码,判断了苹果和梨子是否在水果列表。如果字符串在变量,if语句的条件判断会返回True,并执行相应的代码块,否则不执行。 3. 可以使用elif语句来判断多个字符串是否在一个变量。例如: ```python fruits = ['apple', 'banana', 'orange'] if 'apple' in fruits: print("苹果在水果列表") elif 'banana' in fruits: print("香蕉在水果列表") elif 'orange' in fruits: print("橘子在水果列表") else: print("水果列表没有要查找的水果") ``` 上述代码,先判断苹果是否在水果列表,如果不在,则判断香蕉是否在列表依次类推。如果都不在,就执行else语句块的代码。 通过上述方式,就可以使用if语句来判断多个字符串是否在一个变量。 ### 回答3: 在Python,我们可以使用if语句来判断多个字符串是否在一个变量。首先,我们需要定义一个字符串变量,然后使用if语句来逐个判断这些字符串是否在该变量。 例如,假设我们需要判断"apple"、"banana"和"orange"这三个字符串是否在一个变量fruit。我们可以使用如下代码: fruit = "I like to eat apples and bananas." if "apple" in fruit: print("苹果在fruit") if "banana" in fruit: print("香蕉在fruit") if "orange" in fruit: print("橙子在fruit") 通过运行以上代码,我们可以逐个判断每个字符串是否在fruit变量,并根据判断结果进行相应的操作。 另外,如果我们需要判断多个字符串是否都在该变量,可以使用逻辑运算符and。例如: if "apple" in fruit and "banana" in fruit and "orange" in fruit: print("苹果、香蕉和橙子都在fruit") 通过使用逻辑运算符and,我们可以将多个判断条件组合在一起,只有当所有条件都满足时,才会执行相应的操作。 总之,我们可以使用if语句来判断多个字符串是否在一个变量,并根据判断结果进行相应的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值