Python中子进程输出如何过滤并保存到文件
https://stackoverflow.com/questions/47727133/py3run-a-subprocess-filter-output-then-save-to-a-file
求助,谢谢
Python中子进程输出如何过滤并保存到文件
1 回复
import subprocess
import sys
def filter_and_save_process_output(command, output_file, filter_func=None):
"""
运行子进程,过滤输出并保存到文件
Args:
command: 要执行的命令(列表形式)
output_file: 输出文件名
filter_func: 过滤函数,接收一行文本,返回True保留/False过滤
"""
try:
# 打开输出文件
with open(output_file, 'w', encoding='utf-8') as f:
# 启动子进程
process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, # 合并标准错误到标准输出
text=True,
encoding='utf-8'
)
# 实时读取并处理输出
for line in process.stdout:
# 如果有过滤函数,先过滤
if filter_func is None or filter_func(line):
# 输出到控制台(可选)
sys.stdout.write(line)
sys.stdout.flush()
# 写入文件
f.write(line)
f.flush()
# 等待进程结束
return_code = process.wait()
if return_code != 0:
print(f"进程退出,返回码: {return_code}")
except FileNotFoundError:
print(f"错误:找不到命令 '{command[0]}'")
except Exception as e:
print(f"运行出错: {e}")
# 示例1:过滤包含特定关键词的行
def filter_keyword(line, keywords):
"""保留包含任意关键词的行"""
return any(keyword in line for keyword in keywords)
# 示例2:过滤掉空行和注释
def filter_empty_and_comments(line):
"""过滤空行和以#开头的注释行"""
stripped = line.strip()
return stripped and not stripped.startswith('#')
# 使用示例
if __name__ == "__main__":
# 示例:运行ls命令,只保留包含.py的文件
filter_func = lambda line: '.py' in line
filter_and_save_process_output(
['ls', '-la'],
'filtered_output.txt',
filter_func
)
# 或者使用预定义的过滤函数
keywords = ['error', 'warning', 'info']
custom_filter = lambda line: filter_keyword(line, keywords)
# 运行另一个命令示例
filter_and_save_process_output(
['python', '--version'],
'python_version.txt'
)
这个方案用了subprocess.Popen来启动子进程,通过stdout=subprocess.PIPE捕获输出。关键点在于实时处理:一边读取进程输出,一边应用过滤函数,同时写入文件。filter_func参数让你可以传入自定义的过滤逻辑,比如只保留包含特定关键词的行,或者过滤掉注释行。stderr=subprocess.STDOUT把错误输出合并到标准输出流里,方便统一处理。记得用text=True和encoding='utf-8'确保正确处理文本。
简单说就是边运行边过滤边保存。

