我有一个包含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
答案 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
变量。