Converter número de decimais através de um arquivo de texto

1

A solução desta questão pode girar em torno de perl, sed ou awk e, infelizmente, não estou familiarizado com nenhuma delas.

Meu objetivo é converter um arquivo de texto gerado por computador para dar a ele propriedades mais legíveis para humanos. Para esse fim, desejo processar todos os números com mais de 10 dígitos decimais para algo em torno de: apenas 2. Isso deve ser independente das palavras-chave em torno deles.

Exemplo de arquivo de log:

[General]
Date=2016-01-20
Timestamp=2016-01-20T12:30:00

[Dewpoint]
Low=-17.7041803458378
LTime=14:55
High=-13.1057525836829
HTime=13:42

[Solar]
SunshineHours=4.78333333333332
SunshineHoursToMidnight=0.750000000000001

Saída desejada:

[General]
Date=2016-01-20
Timestamp=2016-01-20T12:30:00

[Dewpoint]
Low=-17.70
LTime=14:55
High=-13.11
HTime=13:42

[Solar]
SunshineHours=4.78
SunshineHoursToMidnight=0.75

O arredondamento não é uma necessidade aqui, isso é truncar seria suficiente para minhas necessidades.

Como eu poderia conseguir isso sem o RTWFM?

    
por Tfb9 21.01.2016 / 01:21

3 respostas

2
awk -F"=" -v OFS="=" '
    NF == 2 &&  ~ /^-?[0-9]*\.[0-9]+$/ { = sprintf("%.2f", )} 
    {print}
' file.log

Isso usa = como o separador de campo. Para linhas com 2 campos e o segundo campo é um float, reformate o segundo campo.

Exibe seus dados de amostra como

[General]
Date=2016-01-20
Timestamp=2016-01-20T12:30:00

[Dewpoint]
Low=-17.70
LTime=14:55
High=-13.11
HTime=13:42

[Solar]
SunshineHours=4.78
SunshineHoursToMidnight=0.75
    
por glenn jackman 21.01.2016 / 02:03
1

Talvez algo assim:

perl -pe 's/(?<==)[-+]?[0-9]*\.?[0-9]+(!:)/sprintf("%.2f",$&)/e' log

que reimprime com precisão 2 qualquer número de ponto flutuante que siga um = e não preceda : (para ignorar os campos de tempo).

Se você não quiser tratar valores inteiros como ponto flutuante, então é um pouco mais simples excluir os campos de tempo, e o seguinte deve fazê-lo:

perl -pe 's/[-+]?[0-9]*\.[0-9]+/sprintf("%.2f",$&)/e' log

A regex de ponto flutuante é obtida de Correspondência de números de ponto flutuante com uma expressão regular

    
por steeldriver 21.01.2016 / 02:09
1

Passar por um pouco de regex deve funcionar

sed -r 's/([0-9]+\.[0-9]{2})[0-9]*//' your_file

Para explicar rapidamente, está procurando:

  • Um dígito
  • Um ponto
  • mais 2 dígitos
  • Qualquer número de dígitos

E está substituindo tudo isso apenas pelos três primeiros. Essencialmente cortando a última parte.

Esse comando apenas mostrará as mudanças. Adicione um -i lá se você quiser editar o arquivo diretamente. Se isso não é realmente um arquivo, você pode redirecionar e redirecionar as coisas para sed também:

$ sed -r 's/([0-9]\.[0-9]{2})[0-9]*//' <<EOF
> [General]
> Date=2016-01-20
> Timestamp=2016-01-20T12:30:00
> 
> [Dewpoint]
> Low=-17.7041803458378
> LTime=14:55
> High=-13.1057525836829
> HTime=13:42
> 
> [Solar]
> SunshineHours=4.78333333333332
> SunshineHoursToMidnight=0.750000000000001
> EOF
[General]
Date=2016-01-20
Timestamp=2016-01-20T12:30:00

[Dewpoint]
Low=-17.70
LTime=14:55
High=-13.10
HTime=13:42

[Solar]
SunshineHours=4.78
SunshineHoursToMidnight=0.75
    
por Oli 21.01.2016 / 01:32