北肙

当你不能够再拥有,唯一可以做的,就是令自己不要忘记。

格式化Linux行式命令输出

写在最前 说来也奇怪,人人都标榜圆满之后的不破不立,但为人初时想做一些规矩之外的事,却被说成是大逆不道。世人皆言,走过千山万水,再看山不是山,才能悟得非常道。你我都没有剧中所言传承之类的秘法,从一无所知修到一无所知,究竟是返璞归真,还是可怜的命运循环。所谓慈悲,都是执著。 当然,说回主题,Linux一众命令可以轻易实现的结果,为何还要做这些毫无意义的事。可能这就是我们这一代人的倔强,是不是苦果子,得自己尝过了才知道。口口声声以肉身证道,凡人哪有什么登天路,不过是拾级而上,守正扶弱而已。 目的 格式化行式命令输出1为字典类型。 代码 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 […]

写在最前

说来也奇怪,人人都标榜圆满之后的不破不立,但为人初时想做一些规矩之外的事,却被说成是大逆不道。世人皆言,走过千山万水,再看山不是山,才能悟得非常道。你我都没有剧中所言传承之类的秘法,从一无所知修到一无所知,究竟是返璞归真,还是可怜的命运循环。所谓慈悲,都是执著。

当然,说回主题,Linux一众命令可以轻易实现的结果,为何还要做这些毫无意义的事。可能这就是我们这一代人的倔强,是不是苦果子,得自己尝过了才知道。口口声声以肉身证道,凡人哪有什么登天路,不过是拾级而上,守正扶弱而已。

目的

格式化行式命令输出1为字典类型。

代码

  1. 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

测试验证

取命令lscpu中:1. 以L1d开头的键值; 2. 以BIOS开头包含关键字name的键值

定义LineCmd对象

方法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)])
                   ])

方法2: 定义YAML文件

---
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}]}]}]}
>>> 

结果验证:

$ python3 ssh.py 
{'L1d cache': '64 KiB (2 instances)', 'BIOS Model name': 'i7-2640M'}

  1. 行式命令输出: 即命令输出内容单行格式为‘键+分隔符+值’的行,如'lscpu'输出某行为'Stepping: 2'。 

Leave a Reply

Your email address will not be published. Required fields are marked *