我有一个包含下一列的表格:
Probe Name Sec_Name Number
A_1 One Bla 2
A_2 One Bla 5
A_3 One Bla 2
B_1 Two bli 1
B_2 Third 6
我想检查第二列中的单元格是否重复,如果重复,则打印第五列及其第四列中数字的平均值。 期望的输出:
Probe Name Sec_Name Number Average
A_1 One Bla 2
A_2 One Bla 5
A_3 One Bla 2 3
B_1 Two bli 1
B_2 Third 6
表格由制表符分隔。我已经尝试过类似的操作,但是...我希望在输出中具有与输入文件中相同的列。
awk '
{
lines[$2]++;
totals[$2] += $4;
}
END {
for (i in lines) {
print i, lines[i], totals[i] totals[i]/lines[i];;
}
}
' file.txt
我希望它或多或少是清楚的......
最佳答案
您可以循环访问该文件两次:
awk 'FNR==NR {a[$2]+=$4; b[$2]++; next}
{printf "%s %s\n", $0, (b[$2]>1?a[$2]/b[$2]:"")}' file file
说明
FNR==NR {a[$2]+=$4; b[$2]++; next}
在第一个循环中,计算第二列的累计值(数组a[]
- 您的totals[]
)。另外,计算它出现的次数(数组b[]
- 你的lines[]
)。{printf "%s %s\n", $0, (b[$2]>1?a[$2]/b[$2]:"")}
在第二个循环中,打印该行以及结果。如果第二列的计数器b[]
大于 1,则仅打印平均值。
测试
$ awk 'FNR==NR {a[$2]+=$4; b[$2]++; next} {printf "%s %s\n", $0, (b[$2]>1?a[$2]/b[$2]:"")}' file file
Probe Name Sec_Name Number
A_1 One Bla 2 3
A_2 One Bla 5 3
A_3 One Bla 2 3
B_1 Two bli 1
B_2 Third 6
更新
根据Kent's great recommendation ,您可以使用以下方法打印上次第二列出现时的平均值:
awk 'FNR==NR {a[$2]+=$4; b[$2]++; c[$2]=FNR; next}
^^^^^^^^^^
{printf "%s %s\n", $0, (b[$2]>1&&c[$2]==FNR?a[$2]/b[$2]:"")}' file file
^^^^^^^^^^^^
它在数组c[]
中捕获上次第二个字段出现的行号。然后打印条件也会检查它,因此如果是最后一次出现第二列,则只打印平均值。
测试
$ awk 'FNR==NR {a[$2]+=$4; b[$2]++; c[$2]=FNR; next} {printf "%s %s\n", $0, (b[$2]>1&&c[$2]==FNR?a[$2]/b[$2]:"")}' a a
Probe Name Sec_Name Number
A_1 One Bla 2
A_2 One Bla 5
A_3 One Bla 2 3
B_1 Two bli 1
B_2 Third 6
关于awk - 当另一列中有相同名称时计算一列的平均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23832303/