如何使用awk打印重复次数大于2次的重复记录
awk按指定字段筛选重复记录实现
需求
使用awk完成文本筛选:
- 字段分隔符为
| - 以第二个字段作为重复判断依据
- 输出符合重复次数要求的所有记录,同字段值的记录按首次出现顺序分组排列
输入数据
1|PTPX9L1Y31QEL55H 2|BWDY6IGYBDTMAVQA 3|6W0Q3WKP3DZ 4|PTPX9L1Y31QEL55H 5|BWDY6IGYBDTMAVQA 6|6W0Q3WKP3DZ 7|81TE22WWDEDCVXBAQ6F20Z86GFW 8|O315L4UB1BGTW03QRQW8L6J3936 9|81TE22WWDEDCVXBAQ6F20Z86GFW 10|81TE22WWDEDCVXBAQ6F20Z86GFW
期望输出
1|PTPX9L1Y31QEL55H 4|PTPX9L1Y31QEL55H 2|BWDY6IGYBDTMAVQA 5|BWDY6IGYBDTMAVQA 3|6W0Q3WKP3DZ 6|6W0Q3WKP3DZ 7|81TE22WWDEDCVXBAQ6F20Z86GFW 9|81TE22WWDEDCVXBAQ6F20Z86GFW 10|81TE22WWDEDCVXBAQ6F20Z86GFW
原有命令问题
之前尝试的命令无法得到正确结果:
awk -F'|' 'NR==FNR{cnt[$2]++; next} cnt[$2]>2' input > output
问题点如下:
- 命令使用了双遍历写法,需要将输入文件传入两次才能触发第二遍的打印逻辑,原命令只传入了一次
input,统计完计数后程序直接结束,不会执行任何打印操作 - 判断条件
cnt[$2]>2会筛选第二字段出现次数大于2(即≥3次)的记录,和期望输出中包含出现2次记录的要求不匹配 - 即使补全文件名、修正判断条件,双遍历直接打印的输出顺序是原文件的行顺序,无法实现同字段记录分组排列的效果
正确实现命令
单遍遍历即可完成需求,不需要重复读取文件,执行效率更高:
awk -F'|' ' !cnt[$2]++ { keys[++key_num] = $2 } { record[$2, cnt[$2]] = $0 } END { for (i=1; i<=key_num; i++) { k = keys[i] if (cnt[k] >= 2) { for (j=1; j<=cnt[k]; j++) { print record[k, j] } } } } ' input > output
逻辑说明
- 首次遇到某个第二字段值时,将该值存入
keys数组,记录字段值的首次出现顺序,保证后续输出的分组顺序符合要求 - 逐行处理时,统计每个第二字段的出现次数,同时将整行内容存入
record二维数组,以「第二字段值+出现序号」作为索引存储 - 最后遍历
keys数组,对于出现次数≥2(即存在重复)的字段,按存储顺序打印该字段对应的所有记录
如果实际需求确实是筛选第二字段出现次数超过2次(即≥3次)的记录,只需要将判断条件修改为
if (cnt[k] > 2)即可,修改后只会输出第二字段为81TE22WWDEDCVXBAQ6F20Z86GFW的3条记录。
内容的提问来源于stack exchange,提问作者user19331398
相关产品推荐
相关产品推荐

