Yet Another Awk Mass
Back in hot_to_wrap_awk_in_shell I released a canned demon by calling awk in awk.
Cooled down by several tins of diet coke and some nethack I realized that I can use getline() to somewhat achieve another somewhat pure awk solution without triggering the quotes-dollar-escaping hell.
The Code
This is it, a shell function to list HBAs in an AIX system with wwpns displayed and colonfied:
lshba() {lsdev -F "name status physloc" | awk '$1 ~ /^fcs.+/ {printf "%s\t%s\t%s\t",$1,$2,$3;tmp = "lscfg -vl "$1; while ((tmp | getline) > 0){FS=".";if (NF==14){printf "%s\t", $NF;for (i=1; i<16; i=i+2){str = sprintf("%s:%s", str, substr($NF, i, 2))};print substr(str, 2);str=""}};close(lscfg);FS=" ";}';}
Ugly…and have it extracted:
$1 ~ /^fcs.+/ { printf "%s\t%s\t%s\t",$1,$2,$3; tmp = "lscfg -vl "$1; while ((tmp | getline) > 0){ FS="."; if (NF==14){ # Ugly lazy but why not? printf "%s\t", $NF; for (i=1; i<16; i=i+2){ str = sprintf("%s:%s", str, substr($NF, i, 2)) }; print substr(str, 2); str="" }; }; close(lscfg); FS=" "; # Don't forget to set it back! }
Some notes:
- Awk's build-in variable and line control shortcuts are there to be used as hard as I can. Otherwise I'll end up writing C instead.
- The trade back of getline() is that it replaced the input and reset the reserved variables. Thus I have to put WWPNs on the last to output, which I use a for loop to apply colons for easy zoning.
- Again, never call awk inside awk!
- Obviously I'm avoiding perl as much I can in my life! :)

Discussion