awk de sambata
Raspunzand la o problema a cuiva de pe rlug, m-am apucat sa scormonesc prin /proc si am constatat ca se pot extrage adresele IP din /proc/net/rt_cache, numai ca sunt intr-un format mai greu de utilizat (in hexa si cu octetii in ordine inversa). Cum tot aveam awk in pipe, am decis sa rezolv problema tot in awk:
awk 'BEGIN {iface="lo"}
function h2d(h, i,x,v){
for(i=1;i<=length(h);++i){
x=index("0123456789ABCDEF",substr(h,i,1));
v=16*v+x-1
}
return v
}
$0 ~ "^"iface {
for (i=1;i<=4;i++) ip[i]=h2d(substr($NF,i*2-1,2));
print ip[4]"."ip[3]"."ip[2]"."ip[1]
}' /proc/net/rt_cache | sort -u
Am pus cateva linebreaks si spatii prin codul awk sa fie mai usor de citit, dar eu il folosesc ca oneliner.
Cateva explicatii:
- functia h2d converteste din hexa in decimal, presupunand ca sursa are doar caracterele 0-9A-F (pentru utilizare normala ar avea nevoie de niste error-checking).
- stiu ca in gawk se poate cu strtonum("0xdeadbeef"), dar asa e mai portabil (si pe sistemul meu am mawk, nu gawk).
- am pus blocul de BEGIN cu numele interfetei pentru ca mi-era mai simplu sa modific acolo decat pe la jumatatea codului awk (de fapt, merge sa declar functia la sfarsit si sa incep direct cu /^lo/ ... ma rog, asa am invatat de $0 ~ "^"iface, pare un idiom util)
- pentru viitoarele dati cand mai scriu cod awk inline, daca import cod dintr-un fisier cu -f , nu mai merge sa-i dau cod inline, ia prmul argument non-optiune drept fisier de date. Solutia bash ar fi cu process substitution (de care am mai scris): awk -f my/code.awk -f <(echo 'inline awk code') /path/to/datafile
Sper ca mai ajuta pe cineva chestia asta, a fost fun.