我在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 -
我可以看到尝试解析这个问题的一些问题,并且对解决方案持开放态度,但我也可能只是做错了这一点; - ):
Self-test routine in progress
流过文字Remaining
Num
列中,9
后的数字未与#
字符分隔空格我可能会离开这里,但这是我第一次尝试解析这个古怪的东西。
感谢大家甚至提前阅读这段文字!
到目前为止,这是我的代码,如果有人认为有必要或认为它有用:
#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")
答案 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一样解析输出