bash

时间:2015-09-29 12:09:12

标签: bash csv awk

我想用

评估一个列
$(echo "1023630 / ln( 10000 /$2 )  / ( 3435 / ln( 10000 /$2 ) - 298 )" | bc -l)

但是在读取文件时会抛出语法错误。我怎么能评估这个? 我试过

while IFS="," read a b c d; do 
    printf "%s,%s,%s,%s\n" $a $(echo "1023630 / ln( 10000 /$b )  / ( 3435 / ln( 10000 /$b ) - 298 )" | bc -l) $c $d; 
done < abcdtemp.csv 

150918021814,1421.5,1,
(sRuntime error (func=(main), adr=26): Function ln not defined.
150918021216,1421.5,1.4,

即使使用awk它也无法正常工作

awk -F',' -v OFS="," '{$2=$(echo "1023630/ln(10000/$2)  / (3435/ln(10000/$2)-298)" | bc -l);$3=$(echo "1023630/ln(10000/$3)  / (3435/ln(10000/$3)-298)" | bc -l);}1' file

awk -F',' -v OFS="," '{$1;$2=printf "%.1f\n","1023630/ln(10000/$2)/(3435/ln(10000/$2)-298)";$3=printf "%.1f\n","1023630/ln(10000/$2)/(3435/ln(10000/$3)-298)";}1' file

任何提示或帮助,我缺少什么?感谢。

2 个答案:

答案 0 :(得分:2)

您的$2可能为空(或某些无效值)。

bc中的自然对数l,而不是ln

最后,在您的awk示例中,代码位于撇号中,因此根本不会对$2进行评估。

答案 1 :(得分:1)

您只需要一个简单的awk脚本:

$ cat file
3,5,7,11

$ while IFS="," read a b c d; do printf "%s,%s,%s,%s\n" $a $(echo "1023630 / l( 10000 /$b ) / ( 3435 / l( 10000 /$b ) - 298 )" | bc -l) $c $d; done < file
3,874.94898530684189106603,7,11

$ awk 'BEGIN{FS=OFS=",";OFMT="%.20f"} {d=log(10000/$2); print $1, 1023630 / d / (3435/d - 298), $3, $4}' file
3,874.94898530684179149830,7,11

它比shell循环更有效,更强大,更便携,并且在其他方​​面都更好。小数点后12位的输出值差异可能与此无关,并且由于工具之间的浮点算术差异。

如果您不相信,请查看在仅长达1,000行的文件上运行每个命令执行的时间,

$ time while IFS="," read a b c d; do printf "%s,%s,%s,%s\n" $a $(echo "1023630 / l( 10000 /$b ) / ( 3435 / l( 10000 /$b ) - 298 )" | bc -l) $c $d; done < file_1k > /dev/null
real    0m39.066s
user    0m7.433s
sys     0m24.458s

$ time awk 'BEGIN{FS=OFS=",";OFMT="%.20f"} {d=log(10000/$2); print $1, 1023630 / d / (3435/d - 298), $3, $4}' file_1k > /dev/null
real    0m0.060s
user    0m0.031s
sys     0m0.031s