0

I was wondering if I could get some help parsing the results from an SNMPWALK call. I know that there a few questions on here associated with almost this exact question. For example I looked at and tried the suggested solutions from these two questions:

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

To begin here is the SNMPWALK command and result I am trying to parse:

SNMPWALK Command:

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

SNMPWALK Result:

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.
...

Basically what I am trying to do is search for "Wireless LAN 802.11(?) PCI-E Nic."; where the ? represents values a-z, and strips away any excess value after the NIC.

So essentially from the list above the only value that would be returned is the Realtek RTL8191SE Wireless LAN 802.11n PCI-E NIC. with the Realtek RTL8191SE portion removed. I would also like for the solution to not return items that have values after the NIC.. For example if give something like this:

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

the solution should reject it based on the additional values at the end.

Here is what my code currently looks like:

        #!/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
       ...

What I have realized from playing around with setting the SNMPWALK command output to an array is that each item gets added in as space separated values. Thus I set IFS to newline delimiter first. Then I tried to match each line based on what I said above.

Community
  • 1
  • 1
NSaid
  • 689
  • 2
  • 16
  • 32
  • [This post should help](http://stackoverflow.com/questions/29613304/is-it-possible-to-escape-regex-metacharacters-reliably-with-sed) – anubhava Mar 25 '16 at 07:06
  • Edit your question to show the expected output given that input. I for one have no idea which part of your input is `the associated MIB` that you want to find. – Ed Morton Mar 26 '16 at 12:37
  • @EdMorton I have updated my question to be a more concise and straightforward. – NSaid Mar 28 '16 at 02:43
  • Oops, you forgot to post your code! StackOverflow is about helping people fix their code. It's not a free coding service. Any code is better than no code at all. Meta-code, even, will demonstrate how you're thinking a program should work, even if you don't know how to write it. The bounty doesn't get you a free pass. – ghoti Mar 28 '16 at 02:53
  • @ghoti updated the question to show the code that I am currently using – NSaid Mar 28 '16 at 03:16

2 Answers2

2

If I understand the question, this should do it:

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

The code in your question can't work as is.

  1. Your (commented) test doesn't match the description of your input data or the sample you provided.
  2. You also haven't included your expected output, but from your description, I'm going to assume that it's 802.11n PCI-E NIC.

First off, if all you want is that output from snmpwalk, the the following might suffice:

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

This uses grep's -o option to return only the part of the line that contains the match.

Or if you want just a portion of that string, you could use:

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

The first grep strips out the "interesting" line from snmpwalk's output. You can of course easily adjust this regex if there's the risk that the string NIC will appear twice on that line. Note that this solution is pretty much shell agnostic; it doesn't require bash, and it'll even work in tcsh.

And of course, to do this in sed is easy enough too:

#!/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)

If you really want to do this in bash with an array, you might construct something like this:

#!/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

Note that readarray requires bash version 4.

Of the two nested assignment lines in this script, the first strips the extraneous characters using sed, and the second strips them using bash "Parameter Expansion" tools. (You can look up how they work in the bash man page.)

ghoti
  • 45,319
  • 8
  • 65
  • 104