按温度列排序并按卡号去重提取最高温记录的Shell命令问题
提取唯一CardNumber最高温度记录的解决方案
需求说明
嘿,我来帮你搞定这个问题!你需要处理分号分隔的数据集,字段顺序是 Date;Name;ID;Region;Empty;CardNumber;Temperature,核心目标是:
- 为每个唯一的CardNumber筛选出对应温度最高的那条记录
- 最终结果按温度列降序排列
输入数据
你的原始输入是所有记录用空格连接在一起的,每条记录的结构是Date;Name;ID;Region;Empty;CardNumber;Temperature,先把它列出来:
1999;D;153;RIZE;;LT1;86 2013;D;153;RIZE;;LT2;88 2012;D;153;RIZE;;LT3;9 2011;D;153;RIZE;;LT4;81 2010;D;153;RIZE;;LT1;75 1888;D;153;RIZE;;LT2;76 2008;D;153;RIZE;;LT3;77 2006;D;153;RIZE;;LT4;78
之前的问题
你尝试的命令:
sort -t ';' -rnk 7 sil3 | sort -u -t ';' -rk 2,6
这个组合的问题在于:第二个sort -u是按第2到6列去重,但它只会保留每组的第一条记录,而之前的排序并没有确保每个CardNumber组的最高温度记录排在最前面,所以得到了无关结果。
正确解决方案
我们可以用tr(拆分记录)+ sort(分组排序)+ awk(去重保留最高温)+ sort(最终排序)的组合来实现,命令如下:
tr ' ' '\n' < input.txt | sort -t ';' -k6,6 -rnk7,7 | awk -F';' '!seen[$6]++' | sort -t ';' -rnk7,7
命令分步解释
咱们拆开来一步步看,确保你明白每一步的作用:
- 拆分记录:
tr ' ' '\n' < input.txt- 把原始输入里连接记录的空格转换成换行,让每条记录单独占一行,方便后续工具处理
- 分组排序:
sort -t ';' -k6,6 -rnk7,7-t ';':指定分隔符为分号-k6,6:先按第6列(CardNumber)分组,把相同CardNumber的记录放在一起-rnk7,7:在同一CardNumber组内,按第7列(Temperature)数值降序排列(r是逆序,n是按数值排序,不是字符串),这样每个组里温度最高的记录会排在最前面
- 去重保留最高温:
awk -F';' '!seen[$6]++'-F';':指定awk的分隔符为分号!seen[$6]++:用数组seen记录已经处理过的CardNumber,只保留每个CardNumber的第一条记录(也就是刚才排序后每组的最高温度记录)
- 最终排序:
sort -t ';' -rnk7,7- 把去重后的结果再按温度列数值降序排列,得到你想要的最终顺序
验证输出
执行上述命令后,得到的结果和你期望的完全一致:
2013;D;153;RIZE;;LT2;88 1999;D;153;RIZE;;LT1;86 2011;D;153;RIZE;;LT4;81 2008;D;153;RIZE;;LT3;77
内容的提问来源于stack exchange,提问作者Eyvz
相关产品推荐
相关产品推荐

