2016-12-31 130 views
1

爲十進制我有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.... 

給出爲u可以看到一些字段具有在科學記數法的值大的csv文件(其考慮到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

如果因爲重複而關閉,請至少將'CONVFMT'解決方案複製到上面鏈接的文章中。 –

+0

csv從哪裏來? Excel xlsx,數據庫?也許你可以改變單元格格式或導出選項,避免數字格式。你甚至可能贏得額外的精度。 –

回答

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

的數值表達式通過用sprintf的替換EXPR(CONVFMT,表達式),除非expr可以在主機上被表示爲一個準確的整數然後它被轉換成的sprintf(「%轉換成字符串d「,expr)。 Sprintf()是一個內置的AWK,它複製了sprintf(3)的功能,而CONVFMT是一個內置變量,用於從數字到字符串的內部轉換,並初始化爲「%.6g」。可以強制顯式類型轉換,expr「」是字符串,expr+0是數字。

所以你可以在開始或格式字段安排CONVFMT變量。

+0

我嘗試用'$ i = sprintf(「%。9f」,$ i)解決這個問題,但是這給我留下了更多的噪音,例如'123400.000000000'。如果從例如'0.000012990'去除尾部零,任何理智的方法?我用'gensub'玩弄,但那只是Gnu awk。 –

+0

@Akshay:輝煌的哥們。你解決了它。非常感謝。對不起,以前沒有回覆,我們有一個黑屏,所有線路都關閉了。 – Zaire

相關問題