Zai*_*ire 3 csv bash shell 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....
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,某些字段具有科学记数法的值(鉴于 csv 文件具有超过 50 亿行的事实,因此不知道所有列都具有科学记数法的值)。
我需要将科学记数法中的值转换为其相应的十进制形式。 我遇到了以下解决方案:在多个字段中将科学记数法转换为十进制并获得以下代码:
#!/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"
}
Run Code Online (Sandbox Code Playgroud)
但是上面的脚本对我不起作用。上面的脚本按原样返回我的输入文件(对于 E+ 值和对于 E- 值),无需转换。我对 shell 脚本很陌生,有什么想法吗?
我正在以这种形式执行脚本:
chmod u+x awkscript.awk
./awkscript.awk inputfile.csv
Run Code Online (Sandbox Code Playgroud)
这可能会帮助你
输入
$ 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....
Run Code Online (Sandbox Code Playgroud)
输出
$ 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....
Run Code Online (Sandbox Code Playgroud)
来自man awk
:
通过用 sprintf(CONVFMT, expr) 替换 expr 将数字表达式转换为字符串,除非 expr 在主机上可以表示为一个精确的整数,否则它将转换为 sprintf("%d", expr)。Sprintf() 是 AWK 内置的,它复制了 sprintf(3) 的功能,CONVFMT 是一个内置变量,用于从数字到字符串的内部转换并初始化为“%.6g”。可以强制显式类型转换,expr "" 是字符串并且expr+0
是数字。
所以你可以CONVFMT
在开始或格式字段上安排变量。
归档时间: |
|
查看次数: |
1786 次 |
最近记录: |