如何从涉及变量的数学运算中导出小数?

如何从涉及变量的数学运算中导出小数?

我正在尝试找到SCALEFACTOR基本上是10000/(sum of 4th column in a file).如何从输出中获取小数?提前感谢任何帮助。

#!/bin/bash

FILES=/path/to/files/*;
for f in ${FILES}
do
    echo $f
    COLTOTAL="$(awk '{sum += $4} END {print sum}' $f)"
    echo "total: ${COLTOTAL}"
#    SCALEFACTOR=`expr 10^5 / $COLTOTAL`
    B=10000
    SCALEFACTOR=$((B / ${COLTOTAL}))
    SCALINGFACTOR=$(echo "100000 / $COLTOTAL" | bc -l
#    echo "scale=5; ${SCALEFACTOR}" | bc
    echo ${SCALEFACTOR}
    awk '{print($1"\t"$2"\t"$3"\t"$4 * ${SCALINGFACTOR})}' $f > $f"_normalized.txt"

done

答案1

for如果文件中包含空格,则实现循环的方式将会中断。如果没有变量 ,它也能正常工作for f in /path/to/files/*,因为扩展以循环可以理解的方式发生for

一般来说,由于启动新进程确实会消耗资源,因此最好只有一个awk和 的实例,正如 @jw013 指出的那样,您必须在 shell 外部执行除法,因为shbash无法进行浮点数学运算。

因为您需要了解文件末尾才能操作每一行,所以您有两个选择:通读每个文件,保存每一行以供第二次通读,或者读取每个文件两次。由于在内存中保存大文件可能会出现问题,因此我选择了第二个选项:

for f in /path/to/files/*; do
  echo "$f"
  awk '
    NR == FNR {
      sum += $4;
      next;
    }
    FNR == 1 {
      print "total: " sum;
      SCALEFACTOR = 10000 / sum;
      print SCALEFACTOR;
    }
    {
      printf("%s\t%s\t%s\t%f\n", $1, $2, $3, $4 * SCALEFACTOR);
    }' "$f" "$f"

NR == FNR表示总记录(行)号与当前文件的记录号相同,这意味着您位于第一个文件,手头的任务是确定总和。 next防止其他子句触发。否则,如果在第二次读取文件的第一行,我们会执行您在awk两次通话之间所做的事情。对于第二次阅读中的每一行,我们打印四个项目,第四个项目按照您指示的比例缩放。

您可以在第四项上使用标准字符串格式,例如您注释的bc五级将更%f改为%.5f

答案2

(echo "scale=5"; echo "100000 / $COLTOTAL") | bc -l

相关内容