#!/bin/bash
# ProcNetstat - bash script to pretty show /proc/net/netstat values
# (C) 2025 Felix Hauri - felix@f-hauri.ch
# This is a sample of doing array manipulation with no loop and no forks!

getMaxLen() { 
    if [[ $1 == -v ]]; then local __set_var=$2; shift 2
    else local __set_var; fi
    local __tmp_string __tmp_array
    printf -v __tmp_string ' %*s' $#	 # Avoid fork to seq 1 $#
    __tmp_array=(${__tmp_string// / .})	 # ${#__tmp_string} == 1+$#
    unset '__tmp_array[0]'		 # drop (0)
    __tmp_array=(${!__tmp_array[@]})	 # now, __tmp_array=(1..$#)
    local __tmp_array="(${__tmp_array[*]/*/[\${#&\}]= })" #([${#1}]= [${#2}]=.. 
    __tmp_array=(${!__tmp_array[@]})	 # array from sorted indexes
    if [[ $__set_var ]]; then printf -v $__set_var %d ${__tmp_array[-1]}
    else echo ${__tmp_array[-1]}	 # last element is max len.
    fi
}

while read -ra line; do			 # read one headers line   
    line[0]="[${line[0]%:}]"		 # 1st field is title
    printf -v str ' %s %%s\n' "${line[@]}" # prepare map
    getMaxLen -v lhw "${line[@]}"        # Left hand's max width
    read -ra line			 # read values line
    line[0]=${line[0]%:}		 # drop colon
    printf -v str "$str" "${line[@]}"	 # finish map
    getMaxLen -v rhw "${line[@]}"	 # Right's hand max width
    mapfile -t line <<< "${str%$'\n'}"	 # map headers with values
    read -a line <<< "${line[*]%%* 0}"	 # drop null values **Warn!
    printf " %-${lhw}s %${rhw}s\n" "${line[@]}" # print out
done < /proc/net/netstat
# Warning: line `read -a line <<<"${line[*]...` will work only while
# there are no space in headers or values! (this could be worked around
# either by replacing space by any character or by playing with IFS)
