用 shell 处理一个文本文件,内容如下:
fdf 284
asd 112
adf 146
csb 513
dfg 576
asd 346
adf 263
csb 092
dfg 547
根据第一列去重,相同的保留第二列值最大的那个,结果数据应该是这样的:
fdf 284
asd 346
adf 263
csb 513
dfg 576
看了下 uniq 命令,好像不支持按字段去重。请问该如何去重呢?
方法一
cat data.txt | sort -rnk2 | awk '{if (!keys[$1]) print $0; keys[$1] = 1;}'
先按照第二列逆序排列,保证数字从大到小输出,然后再用 awk,只有第一列的字符串第一次出现才输出这个字符串,其他的丢弃,这样应该就可以解决问题了。但是这种方法可能会让 awk 占用很多的内存,文件过大的话有问题。
方法二
cat data.txt | sort -k1,1 | awk '{
if (lastKey == $1) {
if (lastValue < $2) {
lastLine = $0;
lastValue = int($2);
}
} else {
if (lastLine) {
print lastLine;
}
lastKey = $1;
lastLine = $0;
lastValue = int($2);
}
} END {
if (lastLine) {
print lastLine;
}
}'
这个方案是按照第一列排序,然后用 awk 筛选结果,筛选的过程相当于一个加强版的 uniq。这个方案在内存使用方面好了很多,不过代码量略多,不是很简洁。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。