Tom*_*Pio 11 awk text-processing sort uniq
我有以下格式的大文件:
2 1019 0 12
2 1019 3 0
2 1021 0 2
2 1021 2 0
2 1022 4 5
2 1030 0 1
2 1030 5 0
2 1031 4 4
Run Code Online (Sandbox Code Playgroud)
如果第2 列中的值匹配,我想对两行的第3 列和第4列中的值求和,否则只是唯一行中值的总和。
所以我希望的输出看起来像这样:
2 1019 15
2 1021 4
2 1022 9
2 1030 6
2 1031 8
Run Code Online (Sandbox Code Playgroud)
我可以根据第2 列使用awk或对文件进行排序,sort并使用 对最后一列求和awk,但仅适用于个别行,而不适用于第 2列匹配的两行。
ter*_*don 12
我会在 Perl 中这样做:
$ perl -lane '$k{"$F[0] $F[1]"}+=$F[2]+$F[3];
END{print "$_ $k{$_}" for keys(%k) }' file
2 1019 15
2 1021 4
2 1030 6
2 1031 8
2 1022 9
Run Code Online (Sandbox Code Playgroud)
或者 awk:
awk '{a[$1" "$2]+=$3+$4}END{for (i in a){print i,a[i]}}' file
Run Code Online (Sandbox Code Playgroud)
如果您希望根据第二列对输出进行排序,您可以直接通过管道传输到sort:
awk '{a[$1" "$2]+=$3+$4}END{for (i in a){print i,a[i]}}' file | sort -k2
Run Code Online (Sandbox Code Playgroud)
请注意,这两种解决方案也包括第一列。这个想法是使用第一列和第二列作为散列(在 perl 中)或关联数组(在 awk 中)的键。每个解决方案的关键是column1 column2,如果两行具有相同的第二列但不同的第一列,则它们将分别分组:
$ cat file
2 1019 2 3
2 1019 4 1
3 1019 2 2
$ awk '{a[$1" "$2]+=$3+$4}END{for (i in a){print i,a[i]}}' file
3 1019 4
2 1019 10
Run Code Online (Sandbox Code Playgroud)
也许这会有所帮助,但第 1 列是否始终为 2,结果是否取决于它?
awk '{ map[$2] += $3 + $4; } END { for (i in map) { print "2", i, map[i] | "sort -t't'" } }' file
Run Code Online (Sandbox Code Playgroud)
或者正如glenn jackman在关于排序的评论中提到的:
gawk '{ map[$2] += $3 + $4; } END { PROCINFO["sorted_in"] = "@ind_str_asc"; for (i in map) { print 2, i, map[i] } }' file
Run Code Online (Sandbox Code Playgroud)