I want to use python3 to parse the output of "command>systeminfo" into json

Viewed 865

I want turn the output of the command systeminfo into json. But I only need some of specific infomation. And I have to avoid the first line (the command line), it's not always in line 1.

How can I achieve this by python3?

I save the output into .txt file. Below is segment of the output.

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

I want it to be like this.

{
    "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",
    }
}
1 Answers
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)

The script executes the command systeminfo and gets the stdout.

The stdout is processed line by line in the for loop and then is split into key and value by using the str.partition method.

If the key name does not start with a space, then it is a root key. If it matches one of the special key names, it will be set with a value of a dictionary type, else it will be set with the current value. The key name is saved to prevkey so that if the else condition is triggered, prevkey can be used as the root key and the key and value will be set to that root key.

The square brackets are removed from the keys in the else condition, though that can be considered an optional preference.

If the dic is something, then it will be written to systeminfo.json.

If you only want certain keys then you can save the keys of interest to a separate dictionary and write that to file.


As the main code for reading from an existing file, use:

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)
Related