我试图将两列中的值除以某个常数。但是,每列中有多个值,并用冒号分隔。该文件非常大(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