bash - counting interface types with awk -


i've got following input:

03:00.0 ethernet controller: broadcom corporation netbooty bcm5111 gigabit ethernet (rev 59) 03:00.1 ethernet controller: broadcom corporation netbooty bcm5111 gigabit ethernet (rev 59) 03:00.2 ethernet controller: broadcom corporation netbooty bcm5111 gigabit ethernet (rev 59) 03:00.3 ethernet controller: broadcom corporation netbooty bcm5111 gigabit ethernet (rev 59) 04:00.0 ethernet controller: broadcom corporation netxtreme ii bcm5709 gigabit ethernet (rev 20) 04:00.1 ethernet controller: broadcom corporation netxtreme ii bcm5709 gigabit ethernet (rev 20) 05:00.0 ethernet controller: broadcom corporation netxtreme ii bcm5709 gigabit ethernet (rev 20) 05:00.1 ethernet controller: broadcom corporation netxtreme ii bcm5709 gigabit ethernet (rev 20) 06:00.0 network controller: intel corporation centrino ultimate-n 6300 (rev 3e) 

this lspci in linux , shows ethernet/wireless devices , corresponding pci ids. in case, output shows me system has 1 quad-port bcm690 nic (i made up), 2 dual-port bcm5709, , intel 6300 wifi controller.

i'm trying write awk logic handle (and more verbose output on more interface-ful systems), printing succinct summary. proposed output format, given above input:

4 broadcom corporation netbooty bcm5111 gigabit ethernet (rev 59) {1x4-port} 4 broadcom corporation netxtreme ii bcm5709 gigabit ethernet (rev 20) {2x2-port} 1 intel corporation centrino ultimate-n 6300 (rev 3e) 

with limited awk knowledge i've far been marginally successful. following i've got, note review files containing lspci -v output other systems, hence '/eth|net/{if ($2 ~ /^eth|^net/) print}' logic ensure right thing.

awk '/eth|net/{if ($2 ~ /^eth|^net/) print}' lspci.txt | awk -f: '{if ($2 ~ /^...0/) pci[$1$2]=$3; count[$3]++} end {for (i in pci) printf "%s %s\n", count[pci[i]], pci[i]}' | uniq -c | awk '{nic=""; (i=3; <=nf; i++) nic = nic $i " "; if ($1 == 1) printf "%s %s\n", $2, nic; if ($1 != 1) printf "%s %s {%dx%d-port}\n", $2, nic, $1, $2/$1}' 

this produces desired output, mostly, uh... i'd love down single awk command. feedback appreciated. examples better. don't need answer spelled out; need pointed examples of similar things. (if you've got better tool job awk, point me towards please.)

awk '{$1 = ""; sub(" ", ""); arr[$0]++} end {for (i in arr) {print arr[i], i}}' 

throw away first field , first field delimiter. use rest of line index counter array. @ end print count , index.

here version prints port count (split out on multiple lines):

awk ' { split($1, slot, ":"); $1 = ""; sub(" ", ""); split($0, type, ":"); iface[type[2]]++; if (!(slot[1] subsep type[2] in slots)) { slots[slot[1], type[2]]; slotcount[type[2]]++ } } end { (ifacetype in iface) { slotc = slotcount[ifacetype]; typec = iface[ifacetype] ports = ""; if (typec > 1) { ports = " {" slotc "x" typec/slotc "-port}" }; print typec, ifacetype, ports } }' 

save slot information in array. discard first field , first delimiter. count interfaces. if haven't seen slot before, remember (simply referring array element creates it). count slots interface type.

for each interface type, slot count , count type. print information. number of ports per interface count of type divided slots occupied type of interface.

by way, double test:

'/eth|net/{if ($2 ~ /^eth|^net/) print}' 

can simplified to:

'$2 ~ /^eth|^net/ {print}' 

Comments

Popular posts from this blog

javascript - backbone.js Collection.add() doesn't `construct` (`initialize`) an object -

php - Get uncommon values from two or more arrays -

Adding duplicate array rows in Php -