我确定这是一个基本问题,但我已经花了大约一个小时就已经完成并且无法弄明白。我正在解析smartctl输出,这是我正在使用的数据样本:
smartctl 5.41 2011-06-09 r3365 [x86_64-linux-2.6.32-39-pve] (local build)
Copyright (C) 2002-11 by Bruce Allen, http://smartmontools.sourceforge.net
=== START OF INFORMATION SECTION ===
Device Model: TOSHIBA MD04ACA500
Serial Number: Y9MYK6M4BS9K
LU WWN Device Id: 5 000039 5ebe01bc8
Firmware Version: FP2A
User Capacity: 5,000,981,078,016 bytes [5.00 TB]
Sector Sizes: 512 bytes logical, 4096 bytes physical
Device is: Not in smartctl database [for details use: -P showall]
ATA Version is: 8
ATA Standard is: Exact ATA specification draft version not indicated
Local Time is: Thu Jul 2 11:24:08 2015 EDT
SMART support is: Available - device has SMART capability.
SMART support is: Enabled
我想要实现的是拔出设备模型(某些设备只是一个字符串,其他设备,例如这个,它是两个字),序列号,时间和其他几个字段。我假设在冒号后捕获所有数据是最容易的,但是如何消除可变数量的空格?
以下是我目前提出的相关代码:
deviceModel = ""
serialNumber = ""
lines = infoMessage.split("\n")
for line in lines:
parts = line.split()
if str(parts):
if parts[0] == "Device Model: ":
deviceModel = parts[1]
elif parts[0] == "Serial Number: ":
serialNumber = parts[1]
vprint(3, "Device model: %s" %deviceModel)
vprint(3, "Serial number: %s" %serialNumber)
我不断得到的错误是:
File "./tester.py", line 152, in parseOutput
if parts[0] == "Device Model: ":
IndexError: list index out of range
我得到错误所说的(有点),但我不确定该范围可能是什么,或者我是否以正确的方式尝试这个。寻找指导让我朝着正确的方向前进。非常感谢任何帮助。
谢谢!
答案 0 :(得分:2)
当split返回长度为1或0的列表并访问第二个元素时,会发生IndexError。当没有找到要分割的东西(空行)时会发生这种情况。
不需要正则表达式:
deviceModel = ""
serialNumber = ""
lines = infoMessage.split("\n")
for line in lines:
if line.startswith("Device Model:"):
deviceModel = line.split(":")[1].strip()
elif line.startswith("Serial Number:"):
serialNumber = line.split(":")[1].strip()
print("Device model: %s" %deviceModel)
print("Serial number: %s" %serialNumber)
答案 1 :(得分:0)
我猜你的问题是中间的空行。因为,
>>> '\n'.split()
[]
你可以做点什么,
>>> f = open('a.txt')
>>> lines = f.readlines()
>>> deviceModel = [line for line in lines if 'Device Model' in line][0].split(':')[1].strip()
# 'TOSHIBA MD04ACA500'
>>> serialNumber = [line for line in lines if 'Serial Number' in line][0].split(':')[1].strip()
# 'Y9MYK6M4BS9K'
答案 2 :(得分:0)
我调试它的方法是在每次迭代时打印出parts
。尝试并向我们展示失败时列表的内容。
编辑:您的问题很可能是@jonrsharpe所说的。当parts
到达空行时,str(parts)
可能是一个空列表,而'[]'
只返回True
var friend_marker = new google.maps
.Marker({
map: map,
position: location,
icon: {
url: icon.png
},
zIndex: 1,
draggable: true
});
。试着测试一下。
答案 3 :(得分:0)
尝试使用正则表达式:
import re
r = re.compile("^[^:]*:\s+(.*)$")
m = r.match("Device Model: TOSHIBA MD04ACA500")
print m.group(1) # Prints "TOSHIBA MD04ACA500"
答案 4 :(得分:0)
不确定您正在运行哪个版本,但在2.7上,line.split()
逐字拆分,所以
>>> parts = line.split()
parts = ['Device', 'Model:', 'TOSHIBA', 'MD04ACA500']
您还可以尝试line.startswith()
找到您想要的行https://docs.python.org/2/library/stdtypes.html#str.startswith
答案 5 :(得分:0)
我认为在这里使用正则表达式要容易得多。
import re
for line in lines:
# Splits the string into at most two parts
# at the first colon which is followed by one or more spaces
parts = re.split(':\s+', line, 1)
if parts:
if parts[0] == "Device Model":
deviceModel = parts[1]
elif parts[0] == "Serial Number":
serialNumber = parts[1]
请注意,如果您只关心这两个字段,startswith
可能会更好。
答案 6 :(得分:0)
分割空白行时,parts
是一个空列表。
您尝试通过检查空列表来容纳它,但是您将空列表转换为一个字符串,使您的条件语句为True。
>>> s = []
>>> bool(s)
False
>>> str(s)
'[]'
>>> bool(str(s))
True
>>>
将if str(parts):
更改为if parts:
。
很多人会说使用try / except块对于Python来说是惯用的
for line in lines:
parts = line.split()
try:
if parts[0] == "Device Model: ":
deviceModel = parts[1]
elif parts[0] == "Serial Number: ":
serialNumber = parts[1]
except IndexError:
pass