1

I would like to get the device ID and Serial Number of a cisco device from show inventory command, I've got the terminal output in a file that looks like this:

show inventory
NAME: "1", DESCR: "WS-C3750G-12S"
PID: WS-C3750G-12S-E   , VID: V06, SN: FDO1129Z9ZJ

NAME: "GigabitEthernet1/0/1", DESCR: "1000BaseLX SFP"
PID:                     , VID:    , SN: H006K022        

NAME: "GigabitEthernet1/0/2", DESCR: "10/100/1000BaseTX SFP"
PID: GLC-T               , VID:    , SN: 00000MTC1444080Z

NAME: "GigabitEthernet1/0/3", DESCR: "1000BaseLX SFP"
PID:                     , VID:    , SN: H006K083        

NAME: "GigabitEthernet1/0/4", DESCR: "1000BaseLX SFP"
PID:                     , VID:    , SN: H006K021        

NAME: "GigabitEthernet1/0/5", DESCR: "1000BaseSX SFP"
PID:                     , VID:    , SN: FNS11190FLE     

NAME: "GigabitEthernet1/0/6", DESCR: "1000BaseSX SFP"
PID:                     , VID:    , SN: P7K08UQ         

NAME: "GigabitEthernet1/0/7", DESCR: "1000BaseLX SFP"
PID:                     , VID:    , SN: H006K032        

NAME: "GigabitEthernet1/0/8", DESCR: "1000BaseLX SFP"
PID:                     , VID:    , SN: H006K040        

NAME: "GigabitEthernet1/0/9", DESCR: "1000BaseLX SFP"
PID:                     , VID:    , SN: FNS14420533     

NAME: "GigabitEthernet1/0/10", DESCR: "1000BaseLX SFP"
PID: GLC-LH-SMD          , VID: V86, SN: FNS16361SG0     

NAME: "GigabitEthernet1/0/11", DESCR: "1000BaseLX SFP"
PID: GLC-LH-SMD          , VID: V86, SN: FNS174002FT     

NAME: "GigabitEthernet1/0/12", DESCR: "1000BaseLX SFP"
PID: GLC-LH-SMD          , VID: V86, SN: FNS183503FS     


Barragan_3750>

I would like to get the SN of the device called "1" and the device name that is behind ">", something like this:

Barragan_3750
SN: FDO1129Z9ZJ

thanks a lot in advance.

1
  • Do you mean WS-C3750G-12S and FDO1129Z9ZJ for the entry with name 1?
    – Kusalananda
    Feb 24, 2017 at 15:36

3 Answers 3

2

Using GNU sed:

$ show inventory | sed -n '/^NAME: "1"/,+1s/^.*, //p'
DESCR: "WS-C3750G-12S"
SN: FDO1129Z9ZJ

The sed editing script will look for lines starting with NAME "1" and apply a substitution to those lines and the first immediately following line.

The substitution will remove everything on the lines up to and including the last comma (and the space just after). The resulting strings are printed to the terminal.

If it's only the serial number and the last line of output you want:

$ show inventory | sed -n -e '/^NAME: "1"/{n;s/^.*, //p}' -e '$p'
SN: FDO1129Z9ZJ
Barragan_3750>

Here, the sed script finds the line as before, but immediately reads the next line (with n) and performs the same substitution as before only on that line. This gives you the serial number.

Then it prints the last line of the input too.

1

Use blank lines as record separator.

If the line matches ' "1", ' save the last field.

Print the last line without the last character and print the saved field.

awk 'BEGIN {RS = ""}
     { if ($0 ~/ "1", /) { serial=$NF } }
     END { print substr($0, 1, length($0)-1) ; print "SN: " serial }' file
1
show inventory | perl -l -00ane '
  /^NAME:\s+"1",/m and $serial_num = "@F[-2,-1]";
  print substr($_,0,-1), $\, $serial_num if eof;
'

A brief summary of the above:

To set the stage stated are the Perl options utilized. We operate Perl in the paragraph mode -00 AND also auto-split mode -a whereby each para is then split up on spaces to populate the @F array each time a new paragraph is read in.

This is what the Perl's $_ looks like after gulping down one para:

NAME: "1", DESCR: "WS-C3750G-12S"

PID: WS-C3750G-12S-E , VID: V06, SN: FDO1129Z9ZJ

IOW, $_ holds a paragraph. Then this $_ is split up on \s+ like this: @F = split /\s+/, $_; This results in the @F array , stating from reverse: $F[-1] = 'FDO1129Z9ZJ'; $F[-2] = 'SN:' ...

And mind you , all of the above happens under the hood. Once that is taken care of we come to the code of the Perl snippet: /^NAME:\s+"",/m => will return true for a record aka para aka $_ when it begins with NAME... or begins with NAME... on a newline due to the pattern modifier /m standing for for multiple-line matching. For that we get the serial number of the as the last field $F[-1] of this para and grab the string SN: as the second-last field $F[-2]. Now we can extract them in one fell swoop like as @F[-2,-1] and put them under double quotes like as "@F[-2,-1]" implying "$F[-2]" space "$F[-1]" something along the lines of that famous shell variable "$@". Meaning we get a space-separated list of array elements. To be accurate, it is the $" superglobal, whose value acts as the separator, just like the first character in IFS determines the double-quoted interpolation of "$*" in bash.

Now we have our serial number of the device, we go look for the device number which is to be found the last record aka eof. Here the substr($_,0,-1) takes the $_ aka para and removes 1 char starting from the end of -1 that's what the - signifies and returns after removing and concatenates the serial_number already determined with the $\ which is stuffed with a \n due to the -l option. This is finally printed on stdout.

Hope I was not very confusing & HTH.

2
  • As perl is rather obscure language for some - could you please explain how that works?
    – user14755
    Feb 25, 2017 at 2:34
  • @DarkHeart. Done. Feb 25, 2017 at 5:02

Not the answer you're looking for? Browse other questions tagged .