Se o Perl estiver disponível:
echo your_string | perl -ne '
BEGIN{ %suffixes=( K => 3, M => 6, G => 9, T => 12, P => 15, E => 18 );
$suffix_regex = join "|", keys %suffixes;
}
s/([0-9][0-9]*(?:\.[0-9]+)?)($suffix_regex)/$1e$suffixes{$2}/g;
printf "%d\n", $_;
'
Como isso deve ser usado como um filtro de texto, é mais apropriado defini-lo como um script perl
e entrada de canal nele. Você pode incorporá-lo dentro de uma função de shell adicionando o seguinte ao seu .bashrc
(supondo que você use o Bash):
myconvert() {
cat <<'EOF' >/dev/null
#!--perl-- -n
BEGIN{ %suffixes=( K => 3, M => 6, G => 9, T => 12, P => 15, E => 18 );
$suffix_regex = join "|", keys %suffixes;
}
s/([0-9][0-9]*(?:\.[0-9]+)?)($suffix_regex)/$1e$suffixes{$2}/g;
printf "%d\n", $_;
__END__
EOF
exec perl -x "/path/to/your/.bashrc"
}
Uma solução usando sed
e bc
:
myconvert(){
sed '
s/\([0-9][0-9]*\(\.[0-9]\+\)\?\)K/*1000/g;
s/\([0-9][0-9]*\(\.[0-9]\+\)\?\)M/*1000000/g;
s/\([0-9][0-9]*\(\.[0-9]\+\)\?\)G/*1000000000/g;
s/\([0-9][0-9]*\(\.[0-9]\+\)\?\)T/*1000000000000/g;
s/\([0-9][0-9]*\(\.[0-9]\+\)\?\)P/*1000000000000000/g;
s/\([0-9][0-9]*\(\.[0-9]\+\)\?\)E/*1000000000000000000/g
' </dev/stdin | bc | sed 's/\..*$//' # Final sed to remove decimal point
}
Uso (o mesmo para as duas soluções):
$ echo '5.23K' | myconvert
5230
$ echo '6.27G' | myconvert
6270000000
Esta solução assume que sua entrada consiste apenas de strings no formato 5.23K
(parte fracionária opcional), caso contrário, bc
não saberá o que fazer com elas.
Nota
O one-liner Perl poderia ter sido inserido como está em uma função shell com < /dev/stdin
como na solução sed
. Isso não passou pela minha cabeça quando escrevi a primeira versão da resposta. Estou deixando o truque perl -x
para o caso de poder beneficiar outra pessoa.