2016-03-25 4 views
0

Мне было интересно узнать, могу ли я получить синтаксический анализ результатов вызова SNMPWALK. Я знаю, что здесь есть несколько вопросов, связанных с этим вопросом. Например, я смотрел и пытался предложенные решения из этих двух вопросов:Bash - Parse snmpwalk output

  1. Parsing snmpwalk output
  2. Parse SNMP output in Bash

Чтобы начать здесь является команда SNMPWALK и результат я пытаюсь разобрать:

SNMPWALK Команда:

snmpwalk -v1 -c public 192.168.2.51 -Ovq IF-MIB::ifDescr 

SNMPWALK Результат:

Software Loopback Interface 1. 
WAN Miniport (SSTP). 
WAN Miniport (L2TP). 
WAN Miniport (PPTP). 
WAN Miniport (PPPOE). 
WAN Miniport (IPv6). 
WAN Miniport (Network Monitor). 
WAN Miniport (IP). 
RAS Async Adapter. 
Atheros AR8152 PCI-E Fast Ethernet Controller. 
Realtek RTL8191SE Wireless LAN 802.11n PCI-E NIC. 
... 

В основном то, что я пытаюсь сделать, это поиск, "Wireless LAN 802.11 PCI-E Nic (?)." где ? представляет значения a-z и удаляет любое избыточное значение после NIC.

По существу из списка выше единственного значения, которое будет возвращено, является Realtek RTL8191SE Wireless LAN 802.11n PCI-E NIC. с удаленной частью Realtek RTL8191SE. Я также хотел бы, чтобы решение не возвращало элементы, имеющие значения после NIC.. Например, если дайте что-то вроде этого:

Realtek RTL8191SE Wireless LAN 802.11n PCI-E NIC - Deterministic Network Enhancer Miniport-VirtualBox NDIS Light-Weight Filter-0000. 

Решение должно отклонить его на основании дополнительных значений в конце.

Вот что мой код в настоящее время выглядит следующим образом:

 #!/bin/bash 
     ... 
     IFS=$'\n' 
     var=($(snmpwalk -v1 -c public -Ovq $1 IF-MIB::ifDescr)) 
     for i in "${var[@]}"; do 
       p=$(echo "$i" | sed 's/^.*\(Wireless LAN 802.11n PCI-E NCI.*\)/\1/') 

     #  if [[ "$p" == "Wireless LAN 802.11n PCI-E NCI." ]]; then 
         echo "$p" 
     #  fi 
     done 
     ... 

То, что я понял из игр с установкой вывода команды SNMPWALK на массив является то, что каждый элемент будет добавлен в качестве разделенных пробелами значений. Таким образом, я сначала устанавливаю IFS в новый разделитель строк. Затем я попытался сопоставить каждую строку, основываясь на том, что я сказал выше.

+0

[Это сообщение должно помочь] (http://stackoverflow.com/questions/29613304/is-it-possible-to-escape-regex-metacharacters-reliably-with-sed) – anubhava

+0

Измените свой вопрос, чтобы показать ожидаемый результат, учитывая этот ввод. Я ни для кого не знаю, какая часть вашего ввода - это «связанная MIB», которую вы хотите найти. –

+0

@EdMorton Я обновил свой вопрос, чтобы быть более кратким и простым. – NSaid

ответ

2

Если я правильно понял вопрос, то это следует сделать это:

snmpwalk -v1 -c public -Ovq $1 IF-MIB::ifDescr | \ 
sed -n 's/.*\(Wireless LAN 802.11[a-z] PCI-E NIC\)$/\1/p' 
1

Код в вашем вопросе не может работать как есть.

  1. Ваш (прокомментированный) тест не соответствует описанию ваших входных данных или образца, который вы предоставили.
  2. Вы также не указали свой ожидаемый результат, но из вашего описания я собираюсь предположить, что это 802.11n PCI-E NIC.

Во-первых, если все, что вы хотите, что выход из snmpwalk, то следующее может быть достаточно:

snmpwalk -v1 -c public -Ovq $1 IF-MIB::ifDescr \ 
| grep -o 'Wireless LAN 802\.11. PCI-E NIC' 

Это использует -o параметр Grep, чтобы вернуть только часть строки, которая содержит матч.

Или, если вы хотите только часть этой строки, вы можете использовать:

snmpwalk -v1 -c public -Ovq $1 IF-MIB::ifDescr \ 
| grep 'Wireless LAN 802\.11. PCI-E NIC' \ 
| grep -o '802\.11.*NIC' 

Первый Grep обрезает на «интересную» линию от выхода snmpwalk в.Вы можете, конечно, легко настроить это регулярное выражение, если есть риск, что строка NIC появится дважды на этой строке. Обратите внимание, что это решение довольно много агностически. он не требует bash, и он даже будет работать в tcsh.

И, конечно же, сделать это в СЭД легко тоже достаточно:

#!/usr/bin/env bash 

sed -ne 's/.*\(Wireless LAN 802\.11. PCI-E NIC\).*/\1/p' \ 
    < <(snmpwalk -v1 -c public -Ovq $1 IF-MIB::ifDescr) 

Если вы действительно хотите сделать это в Баш с массивом, можно построить что-то вроде этого:

#!/usr/bin/env bash 

IFS=$'\n' readarray -t snmpwalk_out < <(snmpwalk -v1 -c public -Ovq $1 IF-MIB::ifDescr) 

for line in "${snmpwalk_out[@]}"; do 
    if [[ "$line" = *"Wireless LAN 802.11"?" PCI-E NIC"* ]]; then 
    line="$(sed 's/.*\(Wireless LAN 802\.11\)/\1/;s/NIC.*/NIC/' <<<"$line")" 
    #line="Wireless LAN 802.11${line##*Wireless LAN 802.11}"; line="${line%%NIC.*}NIC" 
    fi 
done 

Обратите внимание, что readarray требует Баш версии 4.

Из двух вложенных друг в друга линий присваивания в этом сценарии первые полосы лишние символы с использованием СЭД, и го e second разбивает их с помощью инструментов bash «Расширение параметров». (. Вы можете посмотреть, как они работают на странице Баша людей)