通过文本文件转换小数位数

通过文本文件转换小数位数

这个问题的解决方案可能围绕 perl、sed 或 awk,不幸的是我对其中任何一个都不熟悉。

我的目的是将计算机生成的文本文件转换为更易于人类阅读的属性。为此,我希望将所有十进制数字超过 10 位的数字处理为大约 2。这应该与它们周围的关键字无关。

示例日志文件:

[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

期望输出:

[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

这里不需要四舍五入,截断就足以满足我的需要。

如果没有 RTWFM 我该如何实现这一目标?

答案1

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

用作=字段分隔符。对于包含 2 个字段且第 2 个字段为浮点数的行,重新格式化第 2 个字段。

输出样本数据为

[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

答案2

也许是这样的:

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

=它以精度 2 重新打印位于 之后且不在 之前的任何浮点数:(以忽略时间字段)。

如果您不想将整数值视为浮点数,那么排除时间字段会更简单一些,如下所示:

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

浮点正则表达式取自使用正则表达式匹配浮点数

答案3

通过一个小的正则表达式应该可以工作

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

快速解释一下它正在寻找:

  • 数字
  • 一个点
  • 另外 2 位数字
  • 任意数量的数字

它会用前三个替换掉所有部分。本质上就是砍掉最后一部分。

该命令只会输出更改。-i如果您希望它直接编辑文件,请在其中添加一个。如果这实际上不是一个文件,您也可以将内容导入并重定向到sed

$ sed -r 's/([0-9]\.[0-9]{2})[0-9]*/\1/' <<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

相关内容