Para processar a parte do endereço IP, podemos tirar proveito de IFS e divisão de palavras em subshell (portanto, sem coalho $var ) e da capacidade de printf de processar argumentos de tamanho variável para caber na string de formato.
$ ( IFS='.';var='170.170.170.0.156.96';new=$(printf '%02x:' $var); echo ${new:0:${#new}-1} )
aa:aa:aa:00:9c:60
Também vale a pena notar que ${new:0:${#new}-1} é usado para cortar o último caractere : cegamente adicionado por printf .
Considerando que 170.170.170.0.156.96 24 pode vir como uma única sequência de entrada em stdin , poderíamos ler os dois em variáveis e processar separadamente:
$ echo "170.170.170.0.156.96 24" | while read ip num ; do
> hex=$( IFS='.';new=$(printf '%02x:' $ip); echo ${new:0:${#new}-1} );
> printf '%s %d\n' "$hex" "$num"; done
aa:aa:aa:00:9c:60 24
Se você também precisar fazer uso da saída posteriormente no script, considere gravar o valor resultante em pipe nomeado, continuar trabalhando na mesma subzela ou usando a substituição de processo. Veja este para mais informações.