Solução bash pura, sem ferramentas externas usadas para processar as strings, apenas expansão de parâmetros:
#! /bin/bash
str='battery.charge: 90 battery.charge.low: 30 battery.runtime: 3690 battery.voltage: 230.0 device.mfr: MGE UPS SYSTEMS device.model: Pulsar Evolution 500'
IFS=: read -a fields <<< "$str"
for (( i=0 ; i < ${#fields[@]} ; i++ )) ; do
f=${fields[i]}
notfirst=$(( i>0 ))
last=$(( i+1 == ${#fields[@]} ))
(( notfirst )) && echo -n ${f% *}
start=('' $'\n' ' ')
colon=('' ': ')
echo -n "${start[notfirst + last]}${f##* }${colon[!last]}"
done
echo
Explicação: $notfirst
e $last
são booleanos. A parte antes do último espaço ${f% *}
não é impressa para o primeiro campo, pois não existe tal coisa. $start
e $colon
possuem várias strings que separam os campos: no primeiro item, notfirst + last
é 0, então nada é prefixado, para o resto das linhas, $notfirst
é 1, então uma nova linha é impressa, e para a última linha, a adição dá 2, então um espaço é impresso. Em seguida, a parte após o último espaço é impressa em ${f##* }
. O cólon é impresso para todas as linhas, exceto a última.