使用该列的最大值标准化列数据

时间:2015-03-12 06:36:36

标签: awk gawk

我有一个包含两列的数据文件。我想找出第二列的最大数据值,并将第二列的每个条目除以最大值。 (所以我会在第二栏中得到所有条目< = 1.00)。

我尝试使用以下命令:

awk 'BEGIN {max = 0} {if ($2>max) max=$2} {print  ($2/max)}' angleOut.dat

但是我收到如下错误消息。

awk: (FILENAME=angleOut.dat FNR=1) fatal: division by zero attempted

注意:第二列中有一些数据是零值。但是当零值除以最大值时,我应该得到零,但我得到的错误如上所述。

我能为此得到任何帮助吗?

非常感谢提前。

2 个答案:

答案 0 :(得分:5)

让我们将其作为样本输入文件:

$ cat >file
1 5
2 2
3 7
4 6

此awk脚本将规范化第二列:

$ awk 'FNR==NR{max=($2+0>max)?$2:max;next} {print $1,$2/max}' file file
1 0.714286
2 0.285714
3 1
4 0.857143

此脚本读取输入file两次。第一次,它找到了最大值。第二次打印第二列标准化的行。

三元声明

考虑:

max=($2+0>max)?$2:max

这是if-then-else语句的紧凑形式。 "如果"部分是$2+0>max。如果此计算结果为true,则?后面的值将分配给max。如果为false,则:后的值将分配给max

if语句的更明确形式也很有效。

另外,请注意咒语$2+0。在awk中,变量可以是根据上下文的字符串或数字。在字符串上下文中,>比较了词典排序。我们想要一个数字比较。通过向$2添加零,我们将消除所有疑问,并强制awk$2视为一个数字。

答案 1 :(得分:1)

在查看整个文件之前无法确定max,因此需要两次传递。这个使用两个awk执行来获得规范化输出:

awk -vmax=$(awk 'max < $2 { max = $2 } END { print max }' angleOut.dat) \
    '{print $2 / max}' angleOut.dat