在awk中规范化列

时间:2018-11-17 11:36:38

标签: awk normalization

我刚接触awk。

我正在尝试编写一个脚本,该脚本使用一个输入文件,找到第三列的总和,然后打印第1列,第2列,然后打印标准化的第三列。但是,当我执行此操作时,似乎只在输入文件的最后一行执行此操作。我想我缺少有关“ END”工作原理的信息。有提示吗?

谢谢!

BEGIN {
     col= ARGV[2]
     ARGV[2] = ""
}

{s1 += $3}

END {  if (NR > 0){
                print s1;
                print $1, $2, $3/s1
            }
}

输入:

     0          2   8.98002e-05
     1          0   5.66203e-05
     2          2   2.20586e-05
     3          2   5.31672e-05
     4          2   2.17192e-07
     5         26   3.67908e-06
     6          1   1.0385e-05
     7          1   7.78022e-05
     8          0   5.47272e-05
     9          1   6.34726e-05
    10          1   0.000105879
    11          1   4.77847e-05
    12          0   3.05258e-05
    13          0   5.53268e-05
    14          1   7.8916e-05
    15          1   3.02601e-05
    16          1   3.81807e-05

s1:0.000818803

OUTPUT:
0.000818803
0 2 0.109673
0.000818803
1 0 0.0691501
0.000818803
2 2 0.0269401
0.000818803
3 2 0.0649328
0.000818803
4 2 0.000265256
0.000818803
5 26 0.00449324
0.000818803
6 1 0.0126831
0.000818803
7 1 0.0950194
0.000818803
8 0 0.0668381
0.000818803
9 1 0.0775188
0.000818803
10 1 0.129309
0.000818803
11 1 0.0583592
0.000818803
12 0 0.037281
0.000818803
13 0 0.0675703
0.000818803
14 1 0.0963797
0.000818803
15 1 0.0369565
0.000818803
16 1 0.0466299

1 个答案:

答案 0 :(得分:0)

为此,您必须通过记录进行两次遍历。一种方法是按如下所示的第一种方法读取文件本身两次。

第一遍只是累积s1中第3列的总数。第二遍打印前两列和规范化的第三列。

请注意,您必须在命令行上提供两次文件,以便awk对其进行两次处理!

$ awk 'NR == FNR {s1 += $3; next} {print $1, $2, $3/s1}' file file
0 2 0.109673
1 0 0.0691501
2 2 0.0269401
3 2 0.0649329
4 2 0.000265256
5 26 0.00449324
6 1 0.0126832
7 1 0.0950195
8 0 0.0668381
9 1 0.0775188
10 1 0.12931
11 1 0.0583592
12 0 0.037281
13 0 0.0675704
14 1 0.0963798
15 1 0.0369565
16 1 0.0466299

另一种更接近尝试的方式是只读取一次文件,同时将所有行信息都保存在内存中,同时对第3列求和。

然后在END块中,该块在读取所有记录并完全累加后运行,您遍历数组以打印出结果。

 awk '    { s1 += $3; a[NR] = $1 OFS $2; b[NR] = $3 }
      END { for (i=1; i<=NR; ++i) print a[i], b[i] / s1 }' file

第二种方法的明显缺点是要使用更多的内存-实际上,如果文件很大,这种方法甚至是不可行的。

如果您还不熟悉NR == FNR构造,请参见What is "NR==FNR" in awk?。另请参见https://backreference.org/2010/02/10/idiomatic-awk/上有关“双文件处理”的部分。