Você pode usar perl
:
perl -pe 's/[\d+-]+/eval$&/ge' your-file
Ou até mesmo:
perl -pe 's/[\d+-]+/$&/gee' your-file (thanks Rakesh)
Mesmo com zsh
:
set -o extendedglob # for the ## operator (same as ERE +)
while IFS= read -r line; do
printf '%s\n' ${line//(#m)[0-9+-]##/$((MATCH))}
done < your-file
Ou:
zmodload zsh/mapfile
set -o extendedglob
printf %s ${mapfile[your-file]//(#m)[0-9+-]##/$((MATCH))}
Em todos os quatro, procuramos sequências de dígitos, -
e +
caracteres e passamos para o processador aritmético do intérprete ( eval
in perl
(ou a ee
flag que causa a expansão da substituição a ser avaliada como perl
code), $((...))
in zsh
).
Não estamos validando as expressões antes de transmiti-las ao interpretador, por isso pode causar falhas (por exemplo, em sequências como -+-
ou 3++
), mas pelo menos porque estamos considerando apenas dígitos e -
/ +
caracteres, não deve fazer muito mais mal do que reportar uma mensagem de erro e abortar o comando.