How about not using awk at all?
echo 255.255.192.0 | sh -c 'IFS=.; read m ; n=0; for o in $m ; do n=$((($n<<8) + $o)); done; s=$((1<<31)); p=0; while [ $(($n & $s)) -gt 0 ] ; do s=$((s>>1)) p=$((p+1)); done; echo $p'
Annotation: IFS
is the input field separator; it splits the netmask into individual octets. So $m
becomes the set of four numbers. The next variable $n
is going to be the 32 bit number of the netmask, constructed by going over each octed $o
(the iterator in the first loop) and shifting it 8 bits left. The second loop uses $s
(the 'shifter') as a 32 bit number with only a single 1
bit, starting at position 32; while it shifts down it is compared (bitwise &
) to the mask and the return value $p
increases every time there is a 1
until there is no more match (so it stops at the first 0
bit).