我有以下代码:
awk '{h[$1]++}; END { for(k in h) print k, h[k]}' ${infile} >> ${outfile2}
Run Code Online (Sandbox Code Playgroud)
这实现了我想要的部分功能:打印出唯一值,然后还计算这些唯一值出现的次数。现在,我想从每个唯一值中打印出第二列和第三列。由于某种原因,以下似乎不起作用:
awk '{h[$1]++}; END { for(k in h) print k, $2, $3, h[k]}' ${infile} >> ${outfile2}
awk '{h[$1]++}; END { for(k in h) print k, h[$2], h[$3], h[k]}' ${infile} >> ${outfile2}
Run Code Online (Sandbox Code Playgroud)
第一个代码打印出最后一个索引的第二列和第三列,而第二个代码除了 k 和 h[k] 之外什么也不打印。
${infile} 看起来像:
20600 33.8318 -111.9286 -1 0.00 0
20600 33.8318 -111.9286 -1 0.00 0
30900 33.3979 -111.8140 -1 0.00 0
29400 33.9455 -113.5430 -1 0.00 0
30600 33.4461 -111.7876 -1 0.00 0
20600 33.8318 -111.9286 -1 0.00 0
30900 33.3979 -111.8140 -1 0.00 0
30600 33.4461 -111.7876 -1 0.00 0
Run Code Online (Sandbox Code Playgroud)
期望的输出是:
20600, 33.8318, -111.9286, 3
30900, 33.3979, -111.8140, 2
29400, 33.9455, -113.5430, 1
30600, 33.4461, -111.7876, 2
Run Code Online (Sandbox Code Playgroud)
你已经很接近了,你可以在 中完成所有操作awk,但是如果你要存储基于字段 1 的计数,并且还有字段 2 和字段 3 可用于输出END,那么你还需要将字段 2 和 3 存储在索引为的数组中字段 1(或您正在计数的任何字段)。例如你可以这样做:
awk -v OFS=', ' '
{ h[$1]++; i[$1]=$2; j[$1]=$3 }
END {
for (a in h)
print a, i[a], j[a], h[a]
}
' infile
Run Code Online (Sandbox Code Playgroud)
其中h[$1]保存字段 1 用字段 1 索引数组的次数。i[$1]=$2捕获由字段 1 索引的字段 2,然后j[$1]=$3捕获由字段 1 索引的字段 3。
然后END所需要做的就是输出字段 1(a的索引h)、i[a](字段 2)、j[a](字段 3),最后h[a]是字段 1 被看到的次数。
使用/输出示例
使用示例数据,您只需使用正确的文件名在终端上复制/用鼠标中键粘贴代码,例如
$ awk -v OFS=', ' '
> { h[$1]++; i[$1]=$2; j[$1]=$3 }
> END {
> for (a in h)
> print a, i[a], j[a], h[a]
> }
> ' infile
20600, 33.8318, -111.9286, 3
29400, 33.9455, -113.5430, 1
30600, 33.4461, -111.7876, 2
30900, 33.3979, -111.8140, 2
Run Code Online (Sandbox Code Playgroud)
它提供了所需的输出。如果需要按照显示的输出顺序保留记录的顺序,可以使用字符串连接将字段 1、2 和 3 分组为数组的索引,然后输出数组和索引,例如
$ awk '{a[$1", "$2", "$3]++}END{for(i in a) print i ", " a[i]}' infile
20600, 33.8318, -111.9286, 3
30600, 33.4461, -111.7876, 2
29400, 33.9455, -113.5430, 1
30900, 33.3979, -111.8140, 2
Run Code Online (Sandbox Code Playgroud)
检查一下,如果您还有其他问题,请告诉我。