Formatting Linux Line-Style Command Output
A Note Before We Begin Strange as it is, everyone praises breaking through to a new round after completion, but when a person first wants to do something outsid
A Note Before We Begin
Strange as it is, everyone praises breaking through to a new round after completion, but when a person first wants to do something outside the rules, it's called outrageous. The world says: after traveling over mountains and rivers, you see the mountains are no longer mountains, only then can you grasp the extraordinary Way. You and I have no secret techniques passed down from the dramas — going from knowing nothing to knowing nothing, is it a return to the original state, or a pitiful cycle of fate? What is called compassion is but attachment.
Of course, back to the subject — what Linux commands can easily achieve, why bother with all this meaningless effort. Maybe this is the stubbornness of our generation: whether it's a bitter fruit, you have to taste it yourself to know. Always talking about proving the Way with your body, but what kind of mortal has a road to heaven? It's just climbing step by step, upholding the righteous and supporting the weak.
Purpose
Format the row-style command output 1 into a dictionary type.
Code
sshcmd.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from dataclasses import dataclass
@dataclass
class LineFeature:
keyword: str = None
prefix: str = None
suffix: str = None
@dataclass
class DelmtIndexType:
delimiter: str = None
index: int = None
@dataclass
class KeyValuePair:
feature: LineFeature = None
key: list[DelmtIndexType] = None
value: list[DelmtIndexType] = None
@dataclass
class LineCmd:
cmd: str = None
key_value_pairs: list[KeyValuePair] = None
delimiter: str = None
ikey: str = '0:1'
ivalue: str = '1:'
ssh.py
def formatline(self, linecmd: LineCmd = None):
cmd = linecmd.cmd
data = {}
exitcode, output = self.getstatusoutput(cmd)
if exitcode != 0:
return None
def fetch_value(l_info: list[DelmtIndexType] = None,
dataline: str = None) -> str:
for delimiter_index in l_info:
dlm = delimiter_index.delimiter
idx = delimiter_index.index
try:
dataline = dataline.split(dlm)[idx].strip()
except IndexError:
continue
return dataline
if linecmd.delimiter:
for ln in output.split('\n'):
ln = ln.strip()
ikey_from, ikey_to = linecmd.ikey.split(':')
ival_from, ival_to = linecmd.ivalue.split(':')
delimiter = linecmd.delimiter
try:
lst = [l.strip() for l in ln.split(delimiter)]
ikey_from = int(ikey_from)
ival_from = int(ival_from)
try:
ikey_to = int(ikey_to)
except ValueError:
ikey_to = None
try:
ival_to = int(ival_to)
except ValueError:
ival_to = None
key = f'{delimiter}'.join(lst[ikey_from:ikey_to])
value = f'{delimiter}'.join(lst[ival_from:ival_to])
data.update({key: value})
except IndexError:
continue
if not linecmd.key_value_pairs:
return data
for key_value in linecmd.key_value_pairs:
feature = key_value.feature
l_info_key = key_value.key
l_info_value = key_value.value
key_dataline = val_dataline = None
for ln in output.split('\n'):
ln = ln.strip()
pre = feature.prefix
key = feature.keyword
suf = feature.suffix
pre = pre if pre else ''
key = key if key else ''
suf = suf if suf else ''
if ln.startswith(pre) and ln.endswith(suf) and key in ln:
key_dataline = val_dataline = ln.strip()
key_dataline = fetch_value(l_info_key, key_dataline)
val_dataline = fetch_value(l_info_value, val_dataline)
data.update({key_dataline: val_dataline})
return data
Testing & Verification
Get from command lscpu: 1. the key-value starting with L1d; 2. the key-value starting with BIOS that contains the keyword "name"
Define LineCmd Object
Method 1:
line_cmd = LineCmd(cmd='lscpu', key_value_pairs=[
KeyValuePair(feature=LineFeature(prefix='L1d'),
key=[DelmtIndexType(delimiter=':', index=0)],
value=[DelmtIndexType(':', index=1)]),
KeyValuePair(feature=LineFeature(prefix='BIOS', keyword='name'),
key=[DelmtIndexType(delimiter=':', index=0)],
value=[DelmtIndexType(':', 1), DelmtIndexType(' ', 2)])
])
Method 2: define a YAML file
---
sshcmd:
- cmd: 'lscpu'
key_value_pairs:
- feature:
prefix: 'L1d'
key:
- delimiter: ':'
index: 0
value:
- delimiter: ':'
index: 1
- feature:
prefix: 'BIOS'
keyword: 'name'
key:
- delimiter: ':'
index: 0
value:
- delimiter: ':'
index: 1
- delimiter: ' '
index: 2
>>> from yaml import safe_load
>>>
>>> with open('../../devlist/examples/example.ssh.linux.yaml', 'r+') as f:
... line = safe_load(f)
...
>>> line
{'sshcmd': [{'cmd': 'lscpu', 'key_value_pairs': [{'feature': {'prefix': 'L1d'}, 'key': [{'delimiter': ':', 'index': 0}], 'value': [{'delimiter': ':', 'index': 1}]}, {'feature': {'prefix': 'BIOS', 'keyword': 'name'}, 'key': [{'delimiter': ':', 'index': 0}], 'value': [{'delimiter': ':', 'index': 1}, {'delimiter': ' ', 'index': 2}]}]}]}
>>>
Result verification:
$ python3 ssh.py
{'L1d cache': '64 KiB (2 instances)', 'BIOS Model name': 'i7-2640M'}
- Line-format command output: refers to a line whose single-line output follows the 'key+separator+value' format, e.g. one line of
lscpuoutput is 'Stepping: 2'. ↩
评论Comments
加载中…Loading…
留下评论Leave a comment