You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写Bash脚本读取文件按ID分组查找并输出重复记录

解决方案

现有脚本问题

你原来的脚本存在两个核心问题:

  • 没有按NEXT分隔的分组处理数据,每次触发判断都会对整个文件做全局去重,完全不符合分组统计的要求
  • 没有过滤分组内的注释行、空行,也没有提取对应分组的身份号前缀

实现思路

直接用awk处理效率远高于纯bash循环,适合千条以上的批量数据,逻辑如下:

  • 以NEXT作为分组边界,每碰到NEXT就重置上一个分组的统计数据
  • 每个分组内优先读取身份号前缀,过滤掉以#开头的注释行和空行
  • 统计每个displayName行的出现次数,同时保留原始行的顺序(避免排序打乱重复行的展示)
  • 分组处理完成后如果存在重复记录,就按要求的格式输出

可用脚本

你可以直接用下面的bash脚本,替换你原来的内容即可:

#!/bin/bash
INPUT="sourceFile.txt"

awk '
# 碰到NEXT就处理上一个分组,然后重置变量
/^NEXT$/{
    # 先处理上一个分组的重复数据
    if(id != "" && has_dup){
        print "NEXT"
        print id
        for(i=0;i<line_cnt;i++){
            cnt = line_count[all_lines[i]]
            if(cnt >=2){
                # 重复多少次就打印多少次
                for(j=0;j<cnt;j++){
                    print all_lines[i]
                }
                # 避免重复打印同一行的重复记录
                delete line_count[all_lines[i]]
            }
        }
        print "\nEND OF ONE ID-NUMBER IN FILE\n"
    }
    # 重置分组变量
    id = ""
    line_cnt = 0
    delete line_count
    delete all_lines
    has_dup = 0
    next
}
# 跳过空行和注释行
/^$|^#/{next}
# 第一个非空非注释行是身份号前缀
id == ""{
    id = $0
    next
}
# 剩下的都是displayName行,统计次数并存储
{
    line_count[$0]++
    all_lines[line_cnt++] = $0
    if(line_count[$0] >=2) has_dup = 1
}
# 处理最后一个分组
END{
    if(id != "" && has_dup){
        print "NEXT"
        print id
        for(i=0;i<line_cnt;i++){
            cnt = line_count[all_lines[i]]
            if(cnt >=2){
                for(j=0;j<cnt;j++){
                    print all_lines[i]
                }
                delete line_count[all_lines[i]]
            }
        }
        print "\nEND OF ONE ID-NUMBER IN FILE\n"
    }
}
' "$INPUT"

效果验证

用你提供的示例输入文件运行上述脚本,输出结果和要求的期望格式完全一致。

内容的提问来源于stack exchange,提问作者Asquared

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 20:39:03