在csv中将科学记数法转换为十进制

时间:2016-12-31 05:10:09

标签: bash shell csv awk

我有一个包含150列的大型csv文件,其示例如下所示::

id,c1,c2,c3,c4,c5...
1,0,acc,123.4E+03,0,bdd,...
2,1.299E-05,bef,1.666E-08,23,ghh....

正如你可以看到一些字段具有科学记数法的值(考虑到csv文件有超过50亿行的事实,所有列都带有科学记数法的值都是未知的。)

我需要将科学记数法中的值转换为相应的十进制格式。 我遇到了以下解决方案:Convert scientific notation to decimal in multiple fields并获得了以下代码:

#!/usr/bin/awk -f
BEGIN {
d = "[[:digit:]]"
OFS = FS = ","
}
{
delim = ""
for (i = 1; i <= NF; i++) {
    if ($i ~ d "E+" d d d "$") {
        printf "%s%.41f", delim, $i
    }
    else {
        printf "%s%s", delim, $i
    }
    delim = OFS
}
printf "\n"
}

但上面的脚本对我不起作用。上面的脚本按原样返回我的输入文件(对于E +值和E值),没有转换。我对shell脚本很新,有什么想法吗?

我以这种形式执行脚本:

chmod u+x awkscript.awk
./awkscript.awk inputfile.csv

1 个答案:

答案 0 :(得分:3)

这可能对您有所帮助

<强>输入

$ cat f
id,c1,c2,c3,c4,c5...
1,0,acc,123.4E+03,0,bdd,...
2,1.299E-05,bef,1.666E-08,23,ghh....

<强>输出

$ awk 'BEGIN{CONVFMT="%.9f"; FS=OFS=","}{for(i=1; i<=NF; i++)if($i~/^[0-9]+([eE][+-][0-9]+)?/)$i+=0;}1' f
id,c1,c2,c3,c4,c5...
1,0,acc,123400,0,bdd,...
2,0.000012990,bef,0.000000017,23,ghh....

来自man awk

通过将expr替换为sprintf(CONVFMT,expr)将数值表达式转换为字符串,除非expr可以在主机上表示为精确整数,然后将其转换为sprintf(“%d”,expr)。 Sprintf()是一个内置的AWK,它复制了sprintf(3)的功能,而CONVFMT是一个内置变量,用于从数字到字符串的内部转换,并初始化为“%。6g”。可以强制显式类型转换,expr“”是字符串,expr+0是数字。

因此,您可以在开头或格式字段中安排CONVFMT变量。