Python3日常:一键灭掉Chrome浏览器software_reporter_tool.exe进程

针对Chrome更新后software_reporter_tool.exe占用CPU高的问题,本文提供了一个Python脚本解决方案,通过结束进程、删除文件并用同名文件夹占位,有效避免了此问题反复出现。

Chrome每次自动更新后,出现software_reporter_tool.exe占CPU的问题

在日常使用Chrome经常遇到风扇突然狂转的问题,网上搜了一下才发现Chrome目录下会有这样一个程序software_reporter_tool.exe在狂吃CPU(文件位置一般在C:\Users\name\AppData\Local\Google\Chrome\User Data\SwReporter\42.206.200\software_reporter_tool.exe)

解决方案,删掉,并用同名文件夹占位

网上给出的解决方案是,删掉文件,然后用一个同名文件夹占位就行了。
结果好景不长,隔了一段时间Chrome自动更新了,路径变了,比如"SwReporter\42.212.200",可恶的software_reporter_tool.exe又出现了。

考虑用代码实现上面步骤

每次遇到问题,都去手动结束进程,然后去替换文件夹比较烦(平时有登陆不同账号多开Chrome的需求,所以Chrome不止一个),于是便想每次遇到问题的时候,能不能直接用python一步解决。

所以就写了下面代码:
大概思路就是,申请管理员权限,结束所有正在运行的software_reporter_tool.exe进程,找到进程对应的路径,删除该文件,创建文件夹占位。

执行后效果如下:
在这里插入图片描述
在这里插入图片描述

程序实现代码

from __future__ import print_function
import os
import sys
import subprocess
import locale
import time
import ctypes



'''
Author:https://blog.youkuaiyun.com/watfe
Date:2019-08-21
'''


# pyinstaller -F kill_Chrome_software_reporter_tool.exe.py 




banner = '''
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 

                    解决software_reporter_tool.exe高占用问题

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
使用方法:
    当打开Chrome发现有风扇狂响 或 Win任务管理器中有software_reporter_tool.exe在运行时
    双击快捷方式运行,即可完成优化
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
'''
print(banner)





def cmd(command):
    # 执行cmd命令
    result = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE) 
    out,err = result.communicate()
    return out


def is_admin():
    # 获取管理员权限
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False


filename = 'software_reporter_tool.exe'

try:
    
    if is_admin():
        # 可能用到管理员权限执行的部分写在这里

        # 取当前系统代码表,也就是编码格式。
        l_name, l_code = locale.getdefaultlocale()

        # 查找是否存在该进程
        out = cmd('wmic process where name="'+filename +
                '" get processid,executablepath,name')

        # 找到进程对应的路径
        filepath = []
        for i in out.decode(l_code).split('\n'):
            if filename in i:
                filepath.append(i.split(filename)[
                                0].strip().replace('\\', '/').lower())
        filepath = list(set(filepath))
        print('查找进程:成功找到%d个' % len(filepath), filepath)

        #杀掉进程
        print('终止服务:终止所有在运行的'+filename+'服务')
        os.system("taskkill /F /IM "+filename)
        time.sleep(1)  # 等待终止服务运行完毕

        #删除文件
        for i in filepath:
            os.remove(i+filename)
            os.mkdir(i+filename)
            print('删除文件:删除并用同名文件夹占位 %s' % (i+filename))

        print('\n程序执行结束')
        os.system('pause')
    else:
        if sys.version_info[0] == 3:
            ctypes.windll.shell32.ShellExecuteW(
                None, "runas", sys.executable, __file__, None, 1)
        else:  # in python2.x
            ctypes.windll.shell32.ShellExecuteW(None, u"runas", unicode(
                sys.executable), unicode(__file__), None, 1)

    print('\n程序执行结束')


except Exception as e:
    print(e)
    print('\n异常中止')
    os.system('pause')
    

我的Chrome都在D盘,考虑到很多用户的Chrome都是在C盘的。
本来是想exe右键兼容赋予管理员权限的,结果发现网上有其他方法在运行的时候获取管理权限,所以借用了(参考文献:获取管理员权限 https://blog.youkuaiyun.com/qq_17550379/article/details/79006655)

写完代码后,直接用pyinstaller打包成exe

打包好的exe附下载地址:

链接: https://pan.baidu.com/s/1ZZ2fHiOak62Y8BNx-NWD3g 提取码: m6tg

如果有其他更方便的方法,欢迎留言。

写一个python3 脚本,将示例一的文件内容处理成示例二 示例一: test_flt_all_uvlo_1330488680/run_test_flt_all_uvlo.log:UVM_ERROR @ 301935000.000ns: reporter [top_if] ERROR:a_rtl_reg_por_flag_set_rvs_chk. test_flt_all_uvlo_1330488680/run_test_flt_all_uvlo.log:UVM_ERROR : 1 test_flt_all_uvlo_2491396286/run_test_flt_all_uvlo.log:UVM_ERROR : 0 test_flt_all_uvlo_771568176/run_test_flt_all_uvlo.log:UVM_ERROR @ 303975000.000ns: reporter [top_if] ERROR:a_rtl_reg_por_flag_set_rvs_chk. test_flt_all_uvlo_771568176/run_test_flt_all_uvlo.log:UVM_ERROR : 1 test_flt_boot_timeout_abort_165212330/run_test_flt_boot_timeout_abort.log:UVM_ERROR @ 51114000.000ns: reporter [top_if] ERROR:a_rtl_reg_por_flag_set_rvs_chk. test_flt_boot_timeout_abort_165212330/run_test_flt_boot_timeout_abort.log:UVM_ERROR : 1 test_flt_boot_timeout_abort_4063992494/run_test_flt_boot_timeout_abort.log:UVM_ERROR @ 303217000.000ns: reporter [top_if] ERROR:a_rtl_reg_por_flag_set_rvs_chk. test_flt_boot_timeout_abort_4063992494/run_test_flt_boot_timeout_abort.log:UVM_ERROR @ 1841241110.000ns: reporter [top_if] ERROR:a_flt_pwrup_fault_trim_behave_pre_sc_fwd_chk. test_flt_boot_timeout_abort_4063992494/run_test_flt_boot_timeout_abort.log:UVM_ERROR : 2 test_flt_boot_timeout_abort_933958005/run_test_flt_boot_timeout_abort.log:UVM_ERROR @ 301250000.000ns: reporter [top_if] ERROR:a_rtl_reg_por_flag_set_rvs_chk. test_flt_boot_timeout_abort_933958005/run_test_flt_boot_timeout_abort.log:UVM_ERROR @ 4781255000.000ns: reporter [top_if] ERROR:a_rtl_reg_boot_timeout_flag_set_fwd_chk2. test_flt_boot_timeout_abort_933958005/run_test_flt_boot_timeout_abort.log:UVM_ERROR : 2 示例二: test_flt_all_uvlo_1330488680/run_test_flt_all_uvlo.log:UVM_ERROR @ 301935000.000ns: reporter [top_if] ERROR:a_rtl_reg_por_flag_set_rvs_chk. test_flt_boot_timeout_abort_4063992494/run_test_flt_boot_timeout_abort.log:UVM_ERROR @ 1841241110.000ns: reporter [top_if] ERROR:a_flt_pwrup_fault_trim_behave_pre_sc_fwd_chk. test_flt_boot_timeout_abort_933958005/run_test_flt_boot_timeout_abort.log:UVM_ERROR @ 4781255000.000ns: reporter [top_if] ERROR:a_rtl_reg_boot_timeout_flag_set_fwd_chk2.
08-28
<think>根据示例一和示例二,我们可以观察到: 示例一中有多行日志,但示例二中只保留了部分日志行。具体来说,示例二中保留的日志行具有以下特点: 1. 每个不同的日志文件(即不同的路径)只保留一行。 2. 保留的是该文件中具有特定时间戳(即包含“@”符号和ns时间)且包含特定错误信息(ERROR:后面跟着错误代码)的行,而且似乎只保留每个文件中最后出现的那个错误行(或者说是唯一的一个错误行?)?但是观察示例二,实际上每个文件只保留了一行,而且这一行是文件中出现的某个错误行(不一定是最后一个)。 然而,观察示例二: 示例二中的三行分别来自三个不同的文件,并且每个文件只出现一次。 但是,我们再看示例一中的文件: 例如,文件test_flt_all_uvlo_1330488680/run_test_flt_all_uvlo.log有两行错误,但示例二中只保留了第一行(带时间戳的那行)?不对,示例二中并没有这个文件的第一行,而是有另一个文件的一行。 实际上,示例二中的三行分别来自三个不同的文件,而且每个文件只取一行,并且取的是该文件中具有时间戳且错误信息不同的行(即不是重复的错误信息?)。 但是,我们对比示例一和示例二,发现: 示例二中出现的行在示例一中都有,但示例二中只选择了部分行。具体选择规则是: 1. 每个文件只保留一行(但示例二中的每个文件在示例一中都有多行错误,但只保留了一行)。 2. 保留的是该文件中第一个带时间戳的错误行?还是最后一个?或者是有特定错误信息的行? 观察示例一: 对于文件test_flt_all_uvlo_1330488680/run_test_flt_all_uvlo.log,有两行,第一行有时间戳,第二行没有时间戳(只有“UVM_ERROR : 1”)。示例二中并没有保留这个文件的任何一行?不对,示例二中第一行是另一个文件(test_flt_all_uvlo_1330488680)的第一行?但示例二的第一行是: test_flt_all_uvlo_1330488680/run_test_flt_all_uvlo.log:UVM_ERROR @ 301935000.000ns: reporter [top_if] ERROR:a_rtl_reg_por_flag_set_rvs_chk. 而示例一的第一个文件就是这个。 但是,示例二还有另外两行,分别来自另外两个文件,并且每个文件只取了一行。 然而,示例一中,同一个文件有多行,例如: test_flt_boot_timeout_abort_4063992494/run_test_flt_boot_timeout_abort.log 有三行,但示例二中只取了第二行(带时间戳1841241110.000ns的那行)。 所以,规则是:每个文件只取一行,并且取的是该文件中出现的第一个带时间戳的错误行?还是取最后一个?还是取特定的错误信息? 示例二中的三行,在示例一中分别是: 第一行:第一个文件的第一行 第二行:第三个文件的第二行(即第三个文件有三行,取的是第二行) 第三行:第四个文件的第二行(第四个文件有三行,取的是第二行?不对,第四个文件是test_flt_boot_timeout_abort_933958005,有三行,示例二取的是第三行?因为第三行是最后一个错误行?) 但是,示例二第三行是: test_flt_boot_timeout_abort_933958005/run_test_flt_boot_timeout_abort.log:UVM_ERROR @ 4781255000.000ns: reporter [top_if] ERROR:a_rtl_reg_boot_timeout_flag_set_fwd_chk2. 在示例一中,这个文件的三行分别是: 第一行:UVM_ERROR @ 301250000.000ns: ...(第一个错误) 第二行:UVM_ERROR @ 4781255000.000ns: ...(第二个错误) 第三行:UVM_ERROR : 2(没有时间戳,只是错误计数) 所以,示例二取的是这个文件的第二行(因为第三行没有时间戳,所以第二行是最后一个带时间戳的错误行?) 因此,我们总结规则: 1. 对于每个文件,我们只保留一行。 2. 保留的是该文件中最后一个包含时间戳的错误行(即包含“@”和“ns:”的行)。 但是,观察第一个文件test_flt_all_uvlo_1330488680/run_test_flt_all_uvlo.log,它有两行: 第一行:带时间戳 第二行:不带时间戳 那么最后一个带时间戳的行就是第一行(因为第二行没有时间戳,所以第一行就是最后一个带时间戳的行)。 对于文件test_flt_boot_timeout_abort_4063992494/run_test_flt_boot_timeout_abort.log,有三行: 第一行:带时间戳 第二行:带时间戳(另一个时间戳) 第三行:不带时间戳 那么最后一个带时间戳的行是第二行。 对于文件test_flt_boot_timeout_abort_933958005/run_test_flt_boot_timeout_abort.log,有三行: 第一行:带时间戳 第二行:带时间戳(另一个时间戳) 第三行:不带时间戳 那么最后一个带时间戳的行是第二行。 但是,示例二为什么没有出现test_flt_all_uvlo_771568176/run_test_flt_all_uvlo.log这个文件?因为示例二要求每个文件只保留一行,但是示例二中并没有包含所有文件?实际上,示例二中只包含了三个文件,而示例一中有多个文件(从路径看有四个不同的文件?但注意,示例一中有四个不同的路径,但其中两个路径是test_flt_all_uvlo,两个是test_flt_boot_timeout_abort,但每个路径下有不同的数字,所以每个路径都是不同的文件)。 但是,示例二只输出了三行,分别来自三个不同的文件。那么,为什么示例一中的test_flt_all_uvlo_2491396286/run_test_flt_all_uvlo.log没有被输出?因为该文件只有一行,而且这一行没有时间戳(只有“UVM_ERROR : 0”),所以不符合条件(要求带时间戳),因此被跳过。 所以,规则是:对于每个文件,我们只保留最后一个包含时间戳的错误行(如果文件中有至少一行包含时间戳,则保留最后一个包含时间戳的行;如果没有,则跳过该文件)。 因此,处理步骤: 1. 将输入按行分割。 2. 按文件路径分组(因为同一个文件的多行会连续出现?注意示例一中,同一个文件的多行是连续出现的)。 但是,示例一中,同一个文件的多行是连续的。所以我们可以按行读取,然后按行首的路径名分组(即每行开头到第一个冒号之前的部分作为文件路径)。 3. 对于每个文件路径,记录该文件的所有包含时间戳的行(同时记录行内容以及它在文件中的顺序?但我们需要最后一个,所以可以只记录最后一个出现的)。 4. 如果某个文件没有任何包含时间戳的行,则忽略该文件。 5. 最后,将每个文件对应的最后一个包含时间戳的行输出(按什么顺序?示例二中的顺序似乎是按照输入中文件出现的顺序,但每个文件只出现一次,且取最后一个带时间戳的行)。 但是,注意:同一个文件的多行在输入中是连续的,所以我们可以按顺序处理,遇到同一个文件的多行时,我们只保留最后一个带时间戳的行。 具体实现: 我们可以遍历每一行,并提取该行的文件路径(即从行首到第一个冒号的部分)。 然后,我们检查该行是否包含时间戳(即包含“@”和“ns:”),如果包含,则将该行记录为该文件当前找到的最后一个带时间戳的行。 然后,当我们处理完所有行后,每个文件对应的最后一个带时间戳的行就是我们要的。 但是,注意:同一个文件的多行是连续的,但可能不是连续的?在示例一中,同一个文件的多行是连续的。但为了安全,我们可以用字典来记录每个文件的最后一个带时间戳的行。 步骤: 1. 初始化一个字典:file_last_timestamp_line = {} 2. 遍历每一行: line = line.strip() # 去掉首尾空白 if not line: continue # 分割文件路径和内容:第一个冒号之前是文件路径 if &#39;:&#39; not in line: continue parts = line.split(&#39;:&#39;, 1) # 只分割一次 file_path = parts[0] content = parts[1].strip() # 检查内容中是否包含时间戳:这里我们检查是否包含“@”和“ns:”,但注意,有些行可能没有时间戳,所以用这两个特征 if &#39;@&#39; in content and &#39;ns:&#39; in content: # 如果这一行包含时间戳,则更新该文件对应的最后一个带时间戳的行 file_last_timestamp_line[file_path] = line # 注意:这里记录的是整行,因为后面输出整行 3. 遍历结束后,我们得到了一个字典,每个文件(如果有带时间戳的行)对应最后一个带时间戳的行。 4. 但是,输出顺序:按照输入中文件第一次出现的顺序?还是按照字典顺序?示例二中的顺序是示例一中文件第一次出现的顺序吗? 示例一第一个文件是test_flt_all_uvlo_1330488680,然后第二个文件是test_flt_all_uvlo_2491396286(但该文件没有时间戳,所以跳过),第三个文件是test_flt_all_uvlo_771568176,然后第四个文件是test_flt_boot_timeout_abort_165212330,第五个文件是test_flt_boot_timeout_abort_4063992494,第六个文件是test_flt_boot_timeout_abort_933958005。 但是,示例二中输出的顺序是: test_flt_all_uvlo_1330488680/run_test_flt_all_uvlo.log:... test_flt_boot_timeout_abort_4063992494/run_test_flt_boot_timeout_abort.log:... # 注意这是第五个文件 test_flt_boot_timeout_abort_933958005/run_test_flt_boot_timeout_abort.log:... # 第六个文件 所以,跳过了第二个、第三个和第四个文件?不对,第三个文件test_flt_all_uvlo_771568176有带时间戳的行,为什么没有输出? 观察示例一,第三个文件有两行,第一行带时间戳,第二行不带时间戳。所以它的最后一个带时间戳的行就是第一行。但是示例二中没有这一行。 再看示例二,它只输出了三行,分别是第一个文件、第五个文件和第六个文件。为什么第三个文件没有输出?因为示例二要求每个文件只输出一行,但示例二并没有输出所有文件?题目要求是处理成示例二,示例二就是三行。 所以,我们需要再看题目要求:示例二的内容是示例一的一部分,但具体保留哪些行?题目没有明确说明,但观察示例二,它只保留了一些特定的错误信息(比如不是所有错误都保留,只保留特定的错误信息?) 重新阅读题目:写一个脚本将示例一处理成示例二。示例二的内容是示例一中的三行,而且这三行在示例一中分别是第一个文件的第一行、第五个文件的第二行、第六个文件的第二行(按示例一的行号分别是第1行、第7行、第11行)。 但是,题目没有给出保留规则,但观察这三行的共同点:它们都是各自文件中出现的错误,而且错误信息都不是“a_rtl_reg_por_flag_set_rvs_chk.”(第一个文件的是,但第五个文件的是“a_flt_pwrup_fault_trim_behave_pre_sc_fwd_chk”,第六个文件的是“a_rtl_reg_boot_timeout_flag_set_fwd_chk2”),而其他行都是“a_rtl_reg_por_flag_set_rvs_chk.”。 所以,规则可能是:只保留错误信息不是“a_rtl_reg_por_flag_set_rvs_chk.”的行?但是第一个文件保留的就是这个错误,所以不对。 或者,规则是:每个文件只保留第一个出现的错误?但第一个文件保留的是第一个错误,第五个文件保留的是第二个错误(第一个错误是“a_rtl_reg_por_flag_set_rvs_chk”,被跳过),第六个文件保留的也是第二个错误(第一个错误被跳过)。 那么,规则可能是:跳过错误信息为“a_rtl_reg_por_flag_set_rvs_chk.”的行,然后每个文件只保留剩下的行中的第一个?但是第一个文件没有其他错误,所以它保留了第一个错误(虽然错误信息是“a_rtl_reg_por_flag_set_rvs_chk.”,但因为没有其他错误,所以只能保留它?)不对,因为第一个文件有两行,第一行是“a_rtl_reg_por_flag_set_rvs_chk”,第二行是错误计数(不是错误信息,所以忽略)。所以第一个文件只有这一个错误信息。 因此,规则可能是:对于每个文件,只保留第一个出现的非“a_rtl_reg_por_flag_set_rvs_chk”错误信息的行(且带时间戳)?如果没有,则保留第一个带时间戳的行(不管错误信息是什么)? 观察第五个文件(test_flt_boot_timeout_abort_4063992494): 第一行:错误信息是“a_rtl_reg_por_flag_set_rvs_chk.” -> 跳过 第二行:错误信息是“a_flt_pwrup_fault_trim_behave_pre_sc_fwd_chk.” -> 保留 第三行:没有时间戳,跳过 所以,保留第二行。 第六个文件: 第一行:错误信息是“a_rtl_reg_por_flag_set_rvs_chk.” -> 跳过 第二行:错误信息是“a_rtl_reg_boot_timeout_flag_set_fwd_chk2.” -> 保留 第三行:没有时间戳,跳过 第一个文件: 第一行:错误信息是“a_rtl_reg_por_flag_set_rvs_chk.” -> 因为后面没有其他错误行,所以只能保留它。 但是,第二个文件(test_flt_all_uvlo_2491396286)只有一行,错误计数为0,且没有时间戳,所以跳过(不输出)。 第三个文件(test_flt_all_uvlo_771568176): 第一行:错误信息是“a_rtl_reg_por_flag_set_rvs_chk.” -> 跳过?但是后面还有一行,但第二行没有时间戳(错误计数),所以没有其他错误行,那么按照规则,如果没有其他错误行,则保留第一个错误行?但这里没有保留,所以规则是:如果第一个错误行是“a_rtl_reg_por_flag_set_rvs_chk.”,并且后面还有其他错误行(带时间戳),则跳过,否则保留?但这里后面没有带时间戳的其他错误行,所以应该保留?但是示例二没有保留这个文件。 实际上,示例二中没有第三个文件的任何行,所以规则是:如果第一个错误行是“a_rtl_reg_por_flag_set_rvs_chk.”,并且该文件还有其他非“a_rtl_reg_por_flag_set_rvs_chk.”的错误行(带时间戳),则保留第一个非“a_rtl_reg_por_flag_set_rvs_chk.”的错误行;如果该文件只有“a_rtl_reg_por_flag_set_rvs_chk.”这一种错误,则跳过?但第一个文件被保留了,而第一个文件也只有这个错误。 所以,规则不一致。 重新看题目要求:将示例一处理成示例二。示例二的内容就是示例一中的三行,而且这三行在示例一中分别是第1行、第7行、第11行(行号从1开始)。所以,题目要求保留的行是: 第1行:test_flt_all_uvlo_1330488680/run_test_flt_all_uvlo.log:UVM_ERROR @ 301935000.000ns: reporter [top_if] ERROR:a_rtl_reg_por_flag_set_rvs_chk. 第7行:test_flt_boot_timeout_abort_4063992494/run_test_flt_boot_timeout_abort.log:UVM_ERROR @ 1841241110.000ns: reporter [top_if] ERROR:a_flt_pwrup_fault_trim_behave_pre_sc_fwd_chk. 第11行:test_flt_boot_timeout_abort_933958005/run_test_flt_boot_timeout_abort.log:UVM_ERROR @ 4781255000.000ns: reporter [top_if] ERROR:a_rtl_reg_boot_timeout_flag_set_fwd_chk2. 所以,规则可能是:保留示例一中第1行、第7行、第11行?这显然不是通用的规则。 因此,我们必须从示例一和示例二中推断出逻辑规则。 另一种思路:保留每个文件中第一个出现的错误信息(带时间戳)?但是,第一个文件保留的是第一行,第二个文件(test_flt_all_uvlo_2491396286)没有带时间戳的行,所以跳过。第三个文件(test_flt_all_uvlo_771568176)的第一行是带时间戳的错误,但示例二没有保留。第五个文件(test_flt_boot_timeout_abort_4063992494)的第一行是带时间戳的错误,但示例二保留的是第二行(即不是第一行)。所以不是。 保留每个文件中最后一个带时间戳的行,但跳过错误信息为“a_rtl_reg_por_flag_set_rvs_chk.”的行?但是,第五个文件的第一行是“a_rtl_reg_por_flag_set_rvs_chk.”,第二行是其他错误,所以保留第二行。第六个文件同理。第一个文件只有“a_rtl_reg_por_flag_set_rvs_chk.”,所以保留它(尽管是同一个错误,但因为没有其他错误,所以保留)。第三个文件也只有“a_rtl_reg_por_flag_set_rvs_chk.”,所以应该保留,但示例二没有保留。 所以,为什么第三个文件没有被保留?可能是因为第三个文件的错误计数为1(即第二行是“UVM_ERROR : 1”),而第一个文件的错误计数也是1,但第一个文件被保留了,第三个文件却没有。 观察示例二中保留的三个文件,它们的错误计数分别是多少? 第一个文件:错误计数为1(在示例一中它的第二行是“UVM_ERROR : 1”),但示例二只保留了第一行,并没有保留错误计数行。 第五个文件:错误计数为2(第三行) 第六个文件:错误计数为2(第三行) 所以,错误计数不是1的文件才保留?第一个文件错误计数为1,但也被保留了,所以不是。 经过反复对比,我们发现:示例二中保留的三行,它们在示例一中的位置分别是第1行、第7行、第11行,而且这三行都是各自文件中第一次出现的新错误(即错误信息之前没有出现过)?但是,第一个文件中,错误信息只出现一次(第二行是计数,不是新错误),所以保留。第五个文件中,第一行是一个错误,第二行是另一个错误(第一次出现),所以保留第二行。第六个文件同理。 但是,第三个文件,它的错误信息是“a_rtl_reg_por_flag_set_rvs_chk.”,而且这个错误信息在第一个文件中已经出现过了,所以不保留?即:只保留第一次出现的错误信息(以错误信息字符串为唯一标识)所在的行,且每个文件只保留一行(如果该文件有多个错误,取第一个新错误)? 规则:全局范围内,只保留每个错误信息(即ERROR:后面的字符串)的第一次出现。 示例一中的错误信息有: 第1行:a_rtl_reg_por_flag_set_rvs_chk. -> 第一次出现,保留 第2行:错误计数,忽略 第3行:错误计数,忽略 第4行:a_rtl_reg_por_flag_set_rvs_chk. -> 这个错误信息已经出现过(第1行),所以不保留 第5行:错误计数,忽略 第6行:a_rtl_reg_por_flag_set_rvs_chk. -> 出现过,不保留 第7行:a_flt_pwrup_fault_trim_behave_pre_sc_fwd_chk. -> 第一次出现,保留 第8行:错误计数,忽略 第9行:a_rtl_reg_por_flag_set_rvs_chk. -> 出现过,不保留 第10行:a_rtl_reg_boot_timeout_flag_set_fwd_chk2. -> 第一次出现,保留 第11行:错误计数,忽略 所以,我们只需要提取出错误信息(ERROR:后面的部分),然后全局记录哪些错误信息已经出现过。对于每一行,如果该行包含时间戳,并且包含错误信息(以“ERROR:”为标识),提取错误信息字符串,如果这个错误信息是第一次出现,则保留该行,并且标记这个错误信息已经出现过。 注意:有些行只包含错误计数(如“UVM_ERROR : 1”),这些行没有“ERROR:”字符串,所以不会被提取错误信息,也不会被保留。 步骤: 1. 初始化一个集合:seen_errors = set() 2. 遍历每一行: line = line.strip() if not line: continue # 如果行中不包含“ERROR:”或者没有时间戳(即没有“@”和“ns:”),则跳过(因为错误计数行没有“ERROR:”) if &#39;@&#39; not in line or &#39;ns:&#39; not in line or &#39;ERROR:&#39; not in line: continue # 提取错误信息:从“ERROR:”开始到行尾(或到下一个可能的标记,但这里我们直接取“ERROR:”后面的部分) # 注意:错误信息是“ERROR:”后面的字符串,我们取整个后面部分,直到行尾。 # 但是,同一错误信息可能出现在不同文件,我们只关心错误信息字符串,不关心文件。 # 例如,第1行:ERROR:a_rtl_reg_por_flag_set_rvs_chk. # 那么错误信息字符串是“a_rtl_reg_por_flag_set_rvs_chk.” try: # 分割出错误信息部分 # 注意,字符串中可能有多个“ERROR:”,但我们取最后一个?还是第一个?一般只有一个。 # 用字符串的split方法,取最后一个“ERROR:”之后的部分 # 或者,我们找到最后一个“ERROR:”的位置 # 但通常,一个行只有一个ERROR:,所以我们可以用: # 例如:content = line.split(&#39;:&#39;, 1)[1] # 前面已经按第一个冒号分割过文件路径,所以这里line是整行,我们还需要再分割内容部分? # 我们之前并没有分割内容部分,所以这里我们整行处理。 # 先找到“ERROR:”的位置 # 注意:行中可能有多个“ERROR:”,比如:UVM_ERROR @ ...: reporter [top_if] ERROR:... # 所以,我们找到最后一个“ERROR:”? # 观察:错误信息总是在最后,所以我们可以用: # 从行中找到“ERROR:”出现的最后一个位置? # 或者,我们直接分割:以“ERROR:”为分隔符,取最后一部分 parts = line.split(&#39;ERROR:&#39;) if len(parts) < 2: continue error_msg = parts[-1].strip() # 最后一部分就是错误信息 # 但是,错误信息可能包含点号,也可能不包含,我们取到行尾。 # 现在,检查error_msg是否在seen_errors中: if error_msg in seen_errors: # 已经出现过,跳过 continue else: # 这是一个新的错误信息 seen_errors.add(error_msg) # 保留这一行 # 注意:我们要输出的是整行(包括文件路径) print(line) except: continue 但是,这样处理,我们输出的顺序就是输入的顺序,而且只输出第一次出现新错误信息的行。 示例一的行顺序: 第1行:新错误 -> 输出 第4行:错误信息同第1行 -> 跳过 第6行:错误信息同第1行 -> 跳过 第7行:新错误 -> 输出 第9行:错误信息同第1行 -> 跳过 第10行:新错误 -> 输出 所以,输出: 第1行 第7行 第10行 但是,示例二中是第1行、第7行、第11行?不对,第10行是: test_flt_boot_timeout_abort_933958005/run_test_flt_boot_timeout_abort.log:UVM_ERROR @ 4781255000.000ns: reporter [top_if] ERROR:a_rtl_reg_boot_timeout_flag_set_fwd_chk2. 而示例二中的第三行正是这一行(第10行),不是第11行。第11行是错误计数,不会被处理。 所以,我们输出的就是第1行、第7行、第10行,这与示例二完全一致(示例二的三行)。 因此,规则是:提取每一行(带时间戳且带ERROR:的行),然后提取错误信息,如果这个错误信息是第一次出现,则保留该行;否则跳过。 注意:有些行可能没有“ERROR:”(比如只有UVM_ERROR而没有具体的错误信息?),但示例一中,所有带时间戳的行都有“ERROR:”。 所以,代码实现如下: 注意:输入是字符串(示例一的内容),输出是字符串(处理后的内容,即示例二)。 但是,输入可能是多行字符串,输出也是多行字符串(每行是保留的行,保持原样)。 另外,我们不需要对文件进行分组,因为我们是全局判断错误信息是否重复。 因此,我们编写代码: 步骤: seen = set() lines = input_text.splitlines() output_lines = [] for line in lines: line = line.strip() if not line: continue # 检查是否包含时间戳(&#39;@&#39; and &#39;ns:&#39;)和&#39;ERROR:&#39; if &#39;@&#39; not in line or &#39;ns:&#39; not in line or &#39;ERROR:&#39; not in line: continue # 提取错误信息部分:从最后一个&#39;ERROR:&#39;之后开始 # 注意:可能有多个&#39;ERROR:&#39;,我们取最后一个 parts = line.split(&#39;ERROR:&#39;) error_msg = parts[-1].strip() if error_msg in seen: continue else: seen.add(error_msg) output_lines.append(line) # 注意:保留原行,不要修改 # 最后,将output_lines用换行符连接 但是,注意:示例一中,有些行可能包含多个&#39;ERROR:&#39;,但根据示例,我们取最后一个即可。 测试:用示例一作为输入,应该输出三行,即示例二。 因此,我们编写代码。 注意:输入是字符串,输出也是字符串。 但是,题目要求写一个python3脚本,所以我们可以从标准输入读取,然后输出到标准输出。 或者,如果输入是一个文件,则从文件读取。 但题目没有明确,所以我们可以从stdin读取,然后输出到stdout。 代码:</think>根据示例一和示例二的分析,处理规则是:**保留每个唯一错误信息(ERROR:后的字符串)的首次出现行,且只保留包含时间戳(@...ns:)和ERROR:的行**。具体实现如下: ```python import sys def process_logs(input_text): seen_errors = set() output_lines = [] for line in input_text.splitlines(): line = line.strip() if not line: continue # 检查是否包含时间戳和ERROR: if &#39;@&#39; not in line or &#39;ns:&#39; not in line or &#39;ERROR:&#39; not in line: continue # 提取错误信息(最后一个ERROR:后的内容) parts = line.split(&#39;ERROR:&#39;) if len(parts) < 2: continue error_msg = parts[-1].strip() # 如果是新错误类型则保留 if error_msg not in seen_errors: seen_errors.add(error_msg) output_lines.append(line) return &#39;\n&#39;.join(output_lines) if __name__ == "__main__": input_text = sys.stdin.read() result = process_logs(input_text) print(result) ``` ### 代码解释: 1. **初始化集合**:`seen_errors` 用于存储已处理的唯一错误信息。 2. **逐行处理**: - 跳过空行。 - 检查行中是否同时包含 `@`、`ns:` 和 `ERROR:`(时间戳和错误标记)。 3. **提取错误信息**: - 以 `ERROR:` 分割字符串,取最后一部分作为错误信息(避免前缀干扰)。 - 例如:`reporter [top_if] ERROR:a_rtl_reg...` 会提取 `a_rtl_reg...`。 4. **保留首次出现的错误**: - 如果错误信息不在 `seen_errors` 中,则保留该行并添加错误信息到集合。 5. **输出结果**:将所有保留的行用换行符连接输出。 ### 示例验证: - **输入示例一**:包含多个文件和错误类型。 - **输出示例二**: - 保留 `a_rtl_reg_por_flag_set_rvs_chk` 的首次出现(第1行)。 - 保留 `a_flt_pwrup_fault_trim_behave_pre_sc_fwd_chk` 的首次出现(第7行)。 - 保留 `a_rtl_reg_boot_timeout_flag_set_fwd_chk2` 的首次出现(第10行)。 ### 使用方法: ```bash # 从文件读取输入 python3 script.py < input_log.txt # 或直接管道输入 cat input_log.txt | python3 script.py ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值