Linux下按主键去重分隔文件:sort -u未完全去重求助
解决基于指定主键字段的文件去重问题
看起来你遇到的核心问题是:sort -u是按整行完整内容判断重复的,但你的场景需要基于**特定主键字段(第1、6、10字段,分隔符为^X)**去重——哪怕两行主键相同但其他字段有细微差异(比如不可见字符、其他字段值不同),也只保留其中一行。这就是为什么sort -u没能完全去除重复主键的原因:那组残留的重复主键对应的行,整行内容其实存在差异,sort -u会把它们判定为不同行并保留。
正确解决方案:结合sort和awk按主键精准去重
我们可以先按主键字段排序,让相同主键的行聚集在一起,再用awk跟踪已出现的主键,只保留每个主键的第一行(或按需保留最后一行)。
修改你脚本中的去重步骤为:
echo -e "Eliminate the duplicates from the ${FILE_PATH}/TempEX.out file" >> ${LOG} # 按主键字段排序后,用awk仅保留每个主键第一次出现的行 sort -t'^X' -k1,1 -k6,6 -k10,10 ${FILE_PATH}/TempEX.out | awk -F'^X' '!seen[$1,$6,$10]++' > ${DEST_PATH}/myfile_I.out echo -e "Unique records successfully written into ${DEST_PATH}/myfile_I.out" >> ${LOG}
命令细节解释:
sort -t'^X' -k1,1 -k6,6 -k10,10:-t'^X':指定字段分隔符为^X(输入时可通过Ctrl+V再按Ctrl+X来输入这个特殊字符)-k1,1 -k6,6 -k10,10:按第1、6、10字段依次排序,确保拥有相同主键的行连续排列。
awk -F'^X' '!seen[$1,$6,$10]++':-F'^X':设置awk的字段分隔符为^Xseen[$1,$6,$10]:用数组seen记录每个主键组合(第1、6、10字段的拼接值)是否已出现过!seen[...]++:主键第一次出现时,seen[...]初始值为0,取反后为真,输出该行;后续该主键再出现时,seen[...]值大于0,取反后为假,跳过该行。
验证去重效果
执行修改后的脚本后,用你之前的检测命令验证:
cut -d'^X' -f1,6,10 ${DEST_PATH}/myfile_I.out | sort | uniq -d | wc -l
如果返回0,说明所有重复主键已被成功去除。
可选需求:保留重复行中的最后一行
如果你需要保留每个主键对应的最后一行(而非第一行),可以将awk命令替换为:
sort -t'^X' -k1,1 -k6,6 -k10,10 ${FILE_PATH}/TempEX.out | awk -F'^X' '{seen[$1,$6,$10]=$0} END{for(key in seen) print seen[key]}'
这个命令会持续覆盖记录每个主键的最新行,最后统一输出所有主键对应的最终行。
内容的提问来源于stack exchange,提问作者prasanthG
相关产品推荐
相关产品推荐

