Search code examples
arraysbashterminalstring-parsing

Getting multiple strings from SNMPWALK requests via Bash but unsure how to format for output


I haven't had too much experience with bash yet and I'm learning as I go. At work we're needing to use SNMP to pull data from wireless access points. I've been tasked to make a script to loop through a few thousand access points.


I'm pulling multiple strings of data by sequential requests via SNMPWALK. This is how I've set up my input:

IAP=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::iapName -Oqv)
MODEL=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::arrayModel -Oqv | cut -d ',' -f1)
CHANNEL=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::iapChannel -Oqv)
MAXHOUR=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::iapMaxStationsHour -Oqv)
MAXDAY=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::iapMaxStationsDay -Oqv)
MAXWEEK=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::iapMaxStationsWeek -Oqv)
MAXMONTH=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::iapMaxStationsMonth -Oqv)
MAXYEAR=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::iapMaxStationsYear -Oqv)
MAC=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::iapMacAddress -Oqv)

Here's an example of input as printed via echo:

iap1
iap2
iap3
iap4
iap5
iap6
iap7
iap8

XR4820

6
100
11
149
64
112
36
161

9
2
7
2
2
1
3
2

11
5
9
4
8
3
3
3

22
9
21
4
12
4
16
5

24
23
21
5
12
8
20
11

24
23
21
5
12
8
20
11

00:0f:7d:ea:b1:00-01
00:0f:7d:ea:b1:10-11
00:0f:7d:ea:b1:20-21
00:0f:7d:ea:b1:30-31
00:0f:7d:ea:b1:40-41
00:0f:7d:ea:b1:50-51
00:0f:7d:ea:b1:60-61
00:0f:7d:ea:b1:70-71

I need to take the data and output it to CSV. The problem is that I have to get them in order (ex. MODEL[0],CHANNEL[0],. . .,MAC[0],MODEL[1],CHANNEL[1], . . .). I can't seem to do this properly.

I made an attempt to use IFS as suggested by other answers in stackoverflow. I tried creating a for loop to then iterate through the elements:

IAP=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::iapName -Oqv)

if [ "$IAP" != "No Such Instance currently exists at this OID" ]
then

    MODEL=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::arrayModel -Oqv | cut -d ',' -f1)

    CHANNEL=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::iapChannel -Oqv)
    IFS=' ' read -a CHANNEL <<< "$CHANNEL"

    MAXHOUR=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::iapMaxStationsHour -Oqv)
    IFS=' ' read -a MAXHOUR <<< "$MAXHOUR"

    MAXDAY=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::iapMaxStationsDay -Oqv)
    IFS=' ' read -a MAXDAY <<< "$MAXDAY"

    MAXWEEK=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::iapMaxStationsWeek -Oqv)
    IFS=' ' read -a MAXWEEK <<< "$MAXWEEK"

    MAXMONTH=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::iapMaxStationsMonth -Oqv)
    IFS=' ' read -a MAXMONTH <<< "$MAXMONTH"

    MAXYEAR=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::iapMaxStationsYear -Oqv)
    IFS=' ' read -a MAXYEAR <<< "$MAXYEAR"

    MAC=$(snmpwalk -v 2c -c $COMMUNITY $DEVICE XIRRUS-MIB::iapMacAddress -Oqv)      
    IFS=' ' read -a MAC <<< "$MAC"

    for ((i=0; i<${#IAP[@]}; ++i));
    do
        ia=${IAP[$i]}
        m=${MAC[$i]}
        c=${CHANNEL[$i]}
        h=${MAXHOUR[$i]}
        d=${MAXDAY[$i]}
        w=${MAXWEEK[$i]}
        mon=${MAXMONTH[$i]}
        y=${MAXYEAR[$i]}

        if [ -n "$m" ]
        then

            TEMP="$MODEL,$ia,$c,$h,$d,$w,$mon,$y"
            if [ $i -gt 1 ]
            then
                OUTPUT=",$OUTPUT,$TEMP"
            else
                OUTPUT="$TEMP"
            fi

        fi
    done

However, this is the output:

XR4820,iap1
iap2
iap3
iap4
iap5
iap6
iap7
iap8,11,8,11,11,11,11

While it should be:

iap1,6,9,11,22,24,24,iap2,100,2,5,9,23,23,iap3,...

Summarized:

My input is a handful of long strings that I need to parse and send the elements out to a .CSV file. They need to be in order, ie. get elements '0' from each, then elements '1' and so forth. I created a loop that isn't working but still prints some of the data. In my naive opinion the best solution is to convert each variable into an array and iterate through the elements in sequential order.

  • What is the proper way of taking each input variable and turning it into an array? The input for each variable can range from 2 to 16. I need to account for this dynamic sizing
  • Please look at my for loop. How can I simplify it while maintaining the output format? It's a mess from multiple changes
  • If I used IFS to take the data and place it into an array, what would I need to change?

Solution

  • You can make a variable (space delimited) an array byvar=( $var ), but I didn't get your questions completely.

    If you edited your post and summarized the things that you want at the end of it, that would be helpful.

    Edit (based on the comments):

    In the case that your fields are seperated by '\n':

    var1=`echo $var1 | tr "\n" " "`
    var1=( $var1 )