【问题标题】:I want to use python3 to parse the output of "command>systeminfo" into json我想用python3将“command>systeminfo”的输出解析成json
【发布时间】:2018-09-21 10:24:42
【问题描述】:

我想将命令systeminfo 的输出转换成json。 但我只需要一些具体的信息。 而且我必须避免第一行(命令行),它并不总是在第 1 行。

如何通过python3实现这一点?

我将输出保存到 .txt 文件中。 以下是部分输出。

C:\Users\user\Desktop>systeminfo
Host Name:                 COMPUTERHOPE
OS Name:                   Microsoft Windows 10 Pro
OS Version:                10.0.10586 N/A Build 10586
OS Manufacturer:           Microsoft Corporation
OS Configuration:          Standalone Workstation
OS Build Type:             Multiprocessor Free
Registered Owner:          Computerhope
Registered Organization:   Computer Hope
Product ID:                00000-00000-00000-AAAAA
Original Install Date:     12/17/2015, 7:09:50 PM
System Boot Time:          3/28/2016, 6:57:39 AM
System Manufacturer:       Dell Inc.
System Model:              XPS 8300
System Type:               x64-based PC
Processor(s):              1 Processor(s) Installed.
                           [01]: Intel64 Family 6 Model 42 Stepping 7 Genuine Intel ~3401

我希望它是这样的。

{
    "Host Name": "COMPUTERHOPE",
    "OS Name": "Microsoft Windows 10 Pro",
    "OS Version": "10.0.10586 N/A Build 10586",
    "Original Install Date": 
    {
     "Date": "12/17/2015",
     "Time": "7:09:50 PM",
    }
}

【问题讨论】:

    标签: json python-3.x parsing


    【解决方案1】:
    import json, subprocess
    
    def get_systeminfo():
        # Command to run.
        command = ['systeminfo']
    
        # Run the commands and get the stdout.
        with subprocess.Popen(command, universal_newlines=True, stdout=subprocess.PIPE) as p:
            stdout, _ = p.communicate()
    
        return stdout
    
    
    def dic_from_systeminfo(stdout):
        # Dic to store all info.
        dic = {}
    
        # Previous key name saved to reuse for dic values.
        prevkey = ''
    
        # Loop through each line of stdout and split by colon.
        for line in stdout.splitlines():
            key, sep, value = line.partition(':')
    
            if sep == ':':
                value = value.strip()
    
                if not key.startswith(' '):
                    # Assign these keys with values of type dic.
                    if key in ('Original Install Date', 'System Boot Time'):
                        value = {k: v.strip() for k, v in zip(('Date', 'Time'), value.split(','))}
                    elif key in ('Processor(s)', 'Hotfix(s)', 'Network Card(s)'):
                        value = dict()
    
                    # Add to dic and save key name.
                    dic[key] = value
                    prevkey = key
                else:
                    # Remove [] characters and then add key and value to the value type dic.
                    key = key.strip().replace('[', '').replace(']', '')
    
                    if prevkey and isinstance(dic[prevkey], dict):
                        dic[prevkey][key] = value
                    else:
                        print('Warning:', 'dic[' + prevkey + '] is not a dict value.')
    
        return dic
    
    # Run Systeminfo and get stdout.
    stdout = get_systeminfo()
    
    # Get dic from stdout (or read file content).
    dic = dic_from_systeminfo(stdout)
    
    # Write the dic to file.
    if dic:
        with open('systeminfo.json', 'w', encoding='utf-8') as w:
            json.dump(dic, w, indent=4)
    

    脚本执行命令systeminfo 并获取标准输出。

    stdout 在for 循环中逐行处理,然后是 使用str.partition方法拆分成key和value。

    如果键名不以空格开头,则它是根键。 如果它匹配一个特殊的键名,它将被设置为 字典类型的值,否则将设置为当前值。 键名保存到prevkey,这样如果else条件是 触发后,prevkey 可以用作根键和 键和值将设置为该根键。

    在 else 条件下,方括号从键中删除, 虽然这可以被认为是一个可选的偏好。

    如果dic 是某个东西,那么它将被写入systeminfo.json

    如果您只需要某些密钥,则可以将感兴趣的密钥保存到 一个单独的字典并将其写入文件。


    作为读取现有文件的主要代码,使用:

    stdout = ''
    
    # Read from existing file.
    with open('sysinfo.txt') as r:
        stdout = r.read()
    
    # Get dic from stdout (or read file content).
    dic = dic_from_systeminfo(stdout)
    
    # Write the dic to file.
    if dic:
        with open('systeminfo.json', 'w', encoding='utf-8') as w:
            json.dump(dic, w, indent=4)
    

    【讨论】:

    • 如果您没有将命令的运行和标准输出的检索与使用str.partition 对输出的非常干净的解析混为一谈,那么 OP 会更清楚。 OP 已经声明他已将输出捕获到文本文件中。或者将您的答案分成两部分 - 将命令输出检索到文件,然后解析文件。
    • @PaulMcG,根据您的建议更新答案。 get_systeminfo 函数可以省略,文件可以打开、读取,如果需要,可以将内容传递给dic_from_systeminfo 函数。
    • 感谢您的回复。但它有一个错误。 File "par.py", line 41, in dic_from_systeminfo dic[prevkey][key] = value TypeError: 'str' object does not support item assignment.
    • 还有一个问题,因为给出了数据。我可以使用with open('sysinfo.txt') as stdout 作为标准输出吗?
    • 你最后的评论,差不多。避免使用as stdout,因为它将stdout 设置为文件描述符(文件句柄)。请参阅我在底部使用r 作为文件描述符的更新答案。以前的评论,无法复制。 value 被分配给字典,所以是一条奇怪的消息。试试我贴的代码看看是否OK。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-19
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多