Python - 如何解析smartctl程序输出?

时间:2014-02-26 17:43:46

标签: python parsing python-2.7

我在python 2.7.3中编写了一个smartctl包装器......

我有一段时间试图解决如何解析Linux中smartctl程序的输出(特定于Ubuntu x64)

我通过子进程运行smartctl -l selftest /dev/sdx并将输出抓取到变量

将此变量分解为一个列表,然后从输出中删除无用的标题数据和空白行。

现在,我留下了一个字符串列表,这很棒!

数据是表格式的,我想把它解析成一个充满列表的dict()(我认为这是通过阅读文档来表示Python中的表格数据的正确方法)

以下是数据样本:

Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
# 1  Short offline       Completed without error       00%     44796         -
# 2  Short offline       Completed without error       00%     44796         -
# 3  Short offline       Completed without error       00%     44796         -
# 4  Short offline       Completed without error       00%     44796         -
# 5  Short offline       Completed without error       00%     44796         -
# 6  Extended offline    Completed without error       00%     44771         -
# 7  Short offline       Completed without error       00%     44771         -
# 8  Short offline       Completed without error       00%     44741         -
# 9  Short offline       Completed without error       00%         1         -
#10  Short offline       Self-test routine in progress 70%     44813         -

我可以看到尝试解析这个问题的一些问题,并且对解决方案持开放态度,但我也可能只是做错了这一点; - ):

  1. 状态文字Self-test routine in progress流过文字Remaining
  2. 的第一个字符
  3. Num列中,9后的数字未与#字符分隔空格
  4. 我可能会离开这里,但这是我第一次尝试解析这个古怪的东西。

    感谢大家甚至提前阅读这段文字!

    到目前为止,这是我的代码,如果有人认为有必要或认为它有用:

    #testStatus.py
    
    #This module provides an interface for retrieving
    #test status and results for ongoing and completed
    #drive tests
    
    import subprocess
    
    #this function takes a list of strings and removes
    #strings which do not have pertinent information
    def cleanOutput(data):
    
      cleanedOutput = []
    
      del data[0:3] #This deletes records 0-3 (lines 1-4) from the list
    
      for item in data:
        if item == '': #This removes blank items from remaining list
          pass
        else:
          cleanedOutput.append(item)
    
      return cleanedOutput
    
    
    def resultsOutput(data):
    
      headerLines = []
      resultsLines = []
      resultsTable = {}
    
      for line in data:
        if "START OF READ" in line or "log structure revision" in line:
          headerLines.append(line)
        else:
          resultsLines.append(line)
    
      nameLine = resultsLines[0].split()
      print nameLine
    
    
    def getStatus(sdxPath):
      try:
        output = subprocess.check_output(["smartctl", "-l", "selftest", sdxPath])
    
      except subprocess.CalledProcessError:
        print ("smartctl command failed...")
    
      except Exception as e:
        print (e)
    
      splitOutput = output.split('\n')
    
      cleanedOutput = cleanOutput(splitOutput)
    
      resultsOutput(cleanedOutput)
    
    
    #For Testing
    getStatus("/dev/sdb")
    

2 个答案:

答案 0 :(得分:1)

主要的解析问题似乎是前三列;剩下的数据更直接。假设输出在字段之间使用空格(而不是制表字符,这将更容易解析),我会去固定长度解析,如:

num = line[1:2]
desc = line[5:25]
status = line[25:54]
remain = line[54:58]
lifetime = line[60:68]
lba = line[77:99]

标题行的处理方式不同。您将数据放入何种结构取决于您要对其执行的操作。如果您主要想通过该“num”标识符随机访问数据,则以“num”键入的字典可能是合适的。否则列表可能会更好。每个条目(每行)可以是元组,列表,字典,类实例或其他东西。如果要按名称访问字段,则每个条目的字典或类实例可能是合适的。

答案 1 :(得分:0)

关于它的价值(这是一个古老的问题):smartctl具有一个--json标志,您可以使用该标志,然后像从7.0版开始的普通JSON一样解析输出

release notes