2

我很惊讶我在这里找不到这个问题。

我想从 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
4

4 回答 4

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将 end-of-line 定义为\r\n的事实,并且任何出错的不完全 telnet 兼容的服务器几乎肯定会使用 Windows 样式(也\r\n)或 Unix 样式(只是\n)行尾。因此,拆分\n总是会出现在最后一行,即使对于糟糕的服务器也是如此。如果您不需要担心额外的健壮性,您可以拆分\r\n而不是\n.


还有其他方法可以解决这个问题。我可能会使用类似的东西session.expect([r'CPU Utilization\s*: (\d+)\s*%']),或者将会话包装为行的迭代器(如文件),然后只编写标准itertools解决方案。但考虑到你已经拥有的东西,这似乎是最简单的。

于 2013-04-26T19:25:31.680 回答
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()]
于 2013-04-26T19:31:50.080 回答
1

据我了解这个问题,您想从一行中选择 1 行,但不一定是最后一行。

您感兴趣的行始终以“CPU 利用率”开头

这应该有效:

for line in output.splitlines():
  if 'CPU Utilization' in line:
    cpu_utilization = line.split()[-2]
于 2013-04-26T20:02:43.247 回答
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
于 2013-04-26T19:29:19.730 回答