我很惊讶我在这里找不到这个问题。
我想从telnet响应中提取一行并使其成为变量。 (实际上是该行的一个数字)。我可以使用telnet.read_until()提取到我需要的位置,但整个开始仍然存在。打印输出显示机器的不同状态。
我想要获取的行格式如下:
CPU Utilization : 5 %
我真的只需要这个号码,但有很多':'和'%'其余输出中的字符。任何人都可以帮我提取这个价值吗?提前谢谢!
这是我的代码(这会读取整个输出并打印):
import telnetlib, time
print ("Starting Client...")
host = input("Enter IP Address: ")
timeout = 120
print ("Connecting...")
try:
session = telnetlib.Telnet(host, 23, timeout)
except socket.timeout:
print ("socket timeout")
else:
print("Sending Commands...")
session.write("command".encode('ascii') + b"\r")
print("Reading...")
output = session.read_until(b"/r/n/r/n#>", timeout )
session.close()
print(output)
print("Done")
编辑:输出内容的一些示例:
Boot Version : 1.1.3 (release_82001975_C)
Post Version : 1.1.3 (release_82001753_E)
Product VPD Version : release_82001754_C
Product ID : 0x0076
Hardware Strapping : 0x004C
CPU Utilization : 5 %
Uptime : 185 days, 20 hours, 31 minutes, 29 seconds
Current Date/Time : Fri Apr 26 17:50:30 2013
答案 0 :(得分:6)
正如你在问题中所说:
我可以使用
telnet.read_until()
提取到我需要的位置,但整个开始仍然存在。
因此,您可以将所需的所有行(包括您想要的行)添加到变量output
中。你唯一缺少的是如何获得output
字符串中的最后一行,对吧?
这很简单:只需将output
拆分成行并取最后一行:
output.splitlines()[:-1]
或者只是拆掉最后一行:
output.rpartition('\n')[-1]
这不会改变输出,它只是一个计算新值的表达式(output
中的最后一行)。所以,只需这样做,然后是print(output)
,就不会做任何明显有用的事情。
让我们举一个更简单的例子:
a = 3
a + 1
print(a)
这显然会打印3
。如果你想打印4
,你需要这样的东西:
a = 3
b = a + 1
print(b)
所以,回到真实的例子,你想要的可能是这样的:
line = output.rpartition('\n')[-1]
print(line)
现在你会看到这个:
CPU Utilization : 5 %
当然,您仍然需要像Johnny的代码那样从其余部分中提取数字:
numbers = [int(s) for s in line.split() if s.isdigit()]
print(numbers)
现在你会得到这个:
['5']
请注意,它会为您提供一个字符串列表。如果你只想要一个字符串,你还有另一个步骤:
number = numbers[0]
print(number)
这给了你:
5
最后,number
仍然是字符串 '5'
,而不是整数5
。如果您需要,请将最后一位替换为:
number = int(numbers[0])
print(number)
这仍然会打印 5
,但现在您有一个变量,您可以将其实际用作数字:
print(number / 100.0) # convert percent to decimal
我依赖telnet
defines end-of-line as \r\n
的事实,并且任何错误的telnet兼容的服务器几乎肯定会使用Windows风格(也\r\n
)或Unix风格(仅\n
)行结尾。因此,即使对于棘手的服务器,在\n
上拆分也总会得到最后一行。如果您不需要担心额外的稳健性,可以在\r\n
而不是\n
上进行拆分。
还有其他方法可以解决这个问题。我可能要么使用session.expect([r'CPU Utilization\s*: (\d+)\s*%'])
之类的东西,要么将会话包装为行的迭代器(如文件),然后再编写标准的itertools
解决方案。但鉴于你已经拥有的东西,这似乎是最简单的。
答案 1 :(得分:1)
如果您只想获得数字:
>>> output = "CPU Utilization : 5 %"
>>> [int(s) for s in output.split() if s.isdigit()]
[5]
>>> output = "CPU Utilization : 5 % % 4.44 : 1 : 2"
>>> [int(s) for s in output.split() if s.isdigit()]
[5, 4.44, 1, 2]
编辑:
for line in output:
print line # this will print every single line in a loop, so you can make:
print [int(s) for s in line.split() if s.isdigit()]
答案 2 :(得分:1)
据我所知,你想从一个行块中选择1行,但不一定是最后一行。
您感兴趣的行始终以“CPU利用率”
开头这应该有效:
for line in output.splitlines():
if 'CPU Utilization' in line:
cpu_utilization = line.split()[-2]
答案 3 :(得分:0)
In [27]: mystring= "% 5 %;%,;;;;;%"
In [28]: ''.join(c for c in mystring if c.isdigit())
Out[28]: '5'
更快的方式:
def find_digit(mystring):
return filter(str.isdigit, mystring)
find_digit(mystring)
5