NSaid
NSaid

Reputation: 751

Bash - Parse snmpwalk output

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.

Upvotes: 0

Views: 3080

Answers (2)

ghoti
ghoti

Reputation: 46856

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

Upvotes: 1

Cole Tierney
Cole Tierney

Reputation: 10314

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'

Upvotes: 2

Related Questions