很多时候程序的stdout输出包含了动态显示的效果,这些stdout输出如果直接保存为log文件、txt文件,动态效果会消失,并且占用很多行去显示。现在希望输出一个最终文件,使得文件中的显示效果和命令行的stdout显示效果相同
【现象示例】
采用tqdm作为命令行显示,采用>或其他管道命令输出到log文件,用记事本打开,显示效果:

然而命令行中的stdout显示效果:

目标:处理log文件,使其展示效果,与命令行的显示效果相同。
【原因分析】
Unix系统中采用控制字符\r作为回车,\n作为换行。第一个图中的多行显示,每行结尾实际上是\r https://www.cnblogs.com/Andya/p/17384720.html。
【解决方案】
将\r结尾的行覆写,\n结尾的行换行并输出 ,写入新文件即可https://cloud.tencent.com/developer/ask/sof/110346442,用以下脚本实现。使用时保存成脚本,调用方法:Usage: python script.py <path_to_input_log_file> <path_to_output_file>
注意,有的程序在命令行中动态显示效果不是靠\r,而是靠多次\b(退一格)然后覆盖显示实现的,可能需要改写以下脚本中的lastline.endswith判断逻辑。
# coding=utf-8
import sys
import re
def process_log_with_control_chars(input_log_file_path, output_file_path):
try:
with open(input_log_file_path, 'r',newline='') as input_file:
# 读取所有行
lines = input_file.readlines()
# 处理控制字符,只保留最终显示的行
final_output = []
lastline = '\n'
for line in lines:
# 如果行以换行符结束,则认为是新行的开始
if lastline.endswith('\n'):
final_output.append(line)
elif lastline.endswith('\r'):
# 否则,替换最后一行
if final_output:
final_output[-1] = line
lastline = line
with open(output_file_path, 'w') as output_file:
if final_output:
output_file.writelines(final_output)
except FileNotFoundError:
print(f"Error: The file '{input_log_file_path}' does not exist.")
except Exception as e:
print(f"An error occurred: {e}")
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: python script.py <path_to_input_log_file> <path_to_output_file>")
sys.exit(1)
input_log_file_path = sys.argv[1]
output_file_path = sys.argv[2]
process_log_with_control_chars(input_log_file_path, output_file_path)
869

被折叠的 条评论
为什么被折叠?



