如何将列中的多个值除以常量?

如何将列中的多个值除以常量?

我试图将两列中的值除以某个常数。但是,每列中有多个值,并用冒号分隔。该文件非常大(24 个文件,每个 2-3 GB)例如,我的文件的布局为:

1   18  N   112:0:0:0:0:0   126:0:0:0:0:0   19:0:0:0:0:0    20:0:0:0:0:0
1   19  N   0:0:114:0:0:0   0:0:136:0:0:0   0:0:18:0:0:0    0:0:19:0:0:0
1   20  N   0:112:0:0:0:7   0:125:0:0:0:20  0:16:0:0:0:3    0:13:0:0:0:5

我希望输出看起来像这样:

1   18  N   56:0:0:0:0:0    63:0:0:0:0:0    19:0:0:0:0:0    20:0:0:0:0:0
1   19  N   0:0:57:0:0:0    0:0:68:0:0:0    0:0:18:0:0:0    0:0:19:0:0:0
1   20  N   0:56:0:0:0:3.5  0:62.5:0:0:0:10 0:16:0:0:0:3    0:13:0:0:0:5

答案1

这并不完全简单,因为(重复 @berndbausch 的使用想法split),awk 没有将数组展平回字符串的内置方法。我们需要使用 printf,这样做的结果是 awk 忘记了如何很好地对齐输出。

但这确实有效:

#! /usr/bin/gawk -f

function print_div2(arr) {
    split(arr, a, ":")
    printf(" %d", a[1]/2)
    delete a[1]
    for(i in a) printf(":%d", a[i]/2)
}

{
    ORS=""
    print $1, $2, $3 " "
    print_div2($4)
    print " "
    print_div2($5)
    print " "
    ORS="\n"
    print $6, $7
}

注释:ORS 用于抑制任何换行符,print直到我们处理完每条记录为止。我们将字段 4 和 5 赋予 print_div2 函数,该函数将记录分割成一个数组并打印每个条目的一半。

将其放入文件中并将其标记为可执行。用法示例:

$ ./process.awk data.txt
1 18 N  56:0:0:0:0:0  63:0:0:0:0:0 19:0:0:0:0:0 20:0:0:0:0:0
1 19 N  0:0:57:0:0:0  0:0:68:0:0:0 0:0:18:0:0:0 0:0:19:0:0:0
1 20 N  0:56:0:0:0:3  0:62:0:0:0:10 0:16:0:0:0:3 0:13:0:0:0:5

可以使用以下命令恢复整齐的列对齐column

$ ./process.awk data.txt | column -t
1  18  N  56:0:0:0:0:0  63:0:0:0:0:0   19:0:0:0:0:0  20:0:0:0:0:0
1  19  N  0:0:57:0:0:0  0:0:68:0:0:0   0:0:18:0:0:0  0:0:19:0:0:0
1  20  N  0:56:0:0:0:3  0:62:0:0:0:10  0:16:0:0:0:3  0:13:0:0:0:5

答案2

awk '
    function dyd(col, n){
        split(col, t, ":");
        sep=":";
        return t[1]/n sep t[2]/n sep t[3]/n sep t[4]/n sep t[5]/n sep t[6]/n;
    };
{ $4=dyd($4, 2); $5=dyd($5, 2); }1' infile |column -t

相关内容