84669 人が学習中
152542 人が学習中
20005 人が学習中
5487 人が学習中
7821 人が学習中
359900 人が学習中
3350 人が学習中
180660 人が学習中
48569 人が学習中
18603 人が学習中
40936 人が学習中
1549 人が学習中
1183 人が学習中
32909 人が学習中
用 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。这个方案在内存使用方面好了很多,不过代码量略多,不是很简洁。
$ sort -r a.txt | awk '{print $2, $1}' | uniq -f1 | awk '{print $2, $1}' fdf 284 dfg 576 csb 513 asd 346 adf 263
逆排, 反转第一列和第二列, 按第二列去重, 反转第一列和第二列
awk 'BEGIN{ a[$1]=$2 }{ if ($2>a[$1] ) a[$1]=$2 }END{for (i in a) if (i) print i,a[i]}' data.txt
把第一列放入数组 然后对比数组的值 大的就替换掉为新的值
[root@localhost ~]# sort -k2r 1.txt|awk '!a[$1]++' dfg 576 csb 513 asd 346 fdf 284 adf 263
方法一
先按照第二列逆序排列,保证数字从大到小输出,然后再用 awk,只有第一列的字符串第一次出现才输出这个字符串,其他的丢弃,这样应该就可以解决问题了。但是这种方法可能会让 awk 占用很多的内存,文件过大的话有问题。
方法二
这个方案是按照第一列排序,然后用 awk 筛选结果,筛选的过程相当于一个加强版的 uniq。这个方案在内存使用方面好了很多,不过代码量略多,不是很简洁。
逆排, 反转第一列和第二列, 按第二列去重, 反转第一列和第二列
把第一列放入数组 然后对比数组的值 大的就替换掉为新的值