Как я могу прочитать одну строку из ответа telnet с помощью Python?


Я был удивлен, что не смог найти этот вопрос здесь.

Я хотел бы извлечь одну строку из ответа 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")

Edit: некоторый пример того, что выход может быть:

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 2

4 ответа:

Как вы говорите в вопросе:

Я могу извлечь до того места, где мне нужно использовать 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 %

Конечно, вам все еще нужно что-то вроде кода Джонни, чтобы извлечь номер из остальной части строки:
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 определяет конец строки как \r\n, и любой не совсем telnet-совместимый сервер, который ошибается, почти наверняка будет использовать либо Windows-стиль (также \r\n), либо Unix-стиль (просто \n) окончания строк. Итак, расщепление на \n будет всегда получай последнюю строчку, даже для чокнутых серверов. Если вам не нужно беспокоиться об этой дополнительной надежности, вы можете разделить на \r\n вместо \n.


Есть и другие способы вы могли бы решить эту. Я бы, вероятно, либо использовал что-то вроде session.expect([r'CPU Utilization\s*: (\d+)\s*%']), либо обернул сеанс как итератор строк (как файл), а затем просто написал стандартное решение itertools. Но это кажется самым простым, учитывая то, что у вас уже есть.

Как я понимаю, вы хотите выбрать 1 строку из блока строк, но не обязательно последнюю строку.

Строка, которая вас интересует, всегда начинается с "загрузка процессора"

Это должно сработать:

for line in output.splitlines():
  if 'CPU Utilization' in line:
    cpu_utilization = line.split()[-2]

Если вы хотите получить только числа:

>>> 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()]
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