Linux/Bash:每5行分组检测重复组的高效方法
更高效的重复分组检测方案(无需转列还原)
你的思路方向是对的,但转列再对比确实有点绕——其实我们可以直接把5行一组的内容作为整体来处理,不管是用awk直接打包分组,还是用shell工具链快速合并拆分,都能大幅简化操作。下面分享两个实用的实现思路:
思路1:用awk直接处理分组(保留原始顺序)
awk可以直接把每5行打包成一个"虚拟记录",用数组来跟踪重复情况,全程不用转换文件格式,还能完美保留原始行顺序。
BEGIN { group_size = 5 # 定义每组的行数 sep = "\0" # 用null字符作为组内换行的替代(几乎不会出现在文本中,避免冲突) } { # 把当前行追加到当前组的缓存中 current_group = current_group (current_group ? sep : "") $0 line_count++ # 每凑够5行,处理这个分组 if (line_count == group_size) { if (!(current_group in seen)) { # 第一次出现的分组,还原换行并输出 seen[current_group] = 1 gsub(sep, "\n", current_group) print current_group print "---" # 可选:用分隔线区分各组 } else { # 重复分组,可选择跳过或标记 print "[重复分组已跳过]" print "---" } # 重置缓存和计数器 current_group = "" line_count = 0 } } END { # 处理文件末尾可能不足5行的剩余内容 if (line_count > 0) { if (!(current_group in seen)) { gsub(sep, "\n", current_group) print current_group } else { print "[末尾不完整重复分组已跳过]" } } }
使用方式:把代码保存为detect_dups.awk,然后执行:
awk -f detect_dups.awk your_input_file.txt
思路2:用shell工具链快速处理(适合大文件)
如果不需要保留原始顺序,用paste+sort+uniq的组合会更简洁,利用Unix工具的流处理特性,内存占用低,适合处理大文件。
# 统计所有分组的重复次数,并还原格式 paste -d "\0" - - - - - < your_input_file.txt | sort | uniq -c | while read count line; do echo "🔄 出现次数: $count" echo "$line" | tr "\0" "\n" echo "------------------------" done # 如果只想保留唯一分组(去重后输出) paste -d "\0" - - - - - < your_input_file.txt | sort -u | tr "\0" "\n"
原理说明:
paste -d "\0" - - - - -:把每5行合并成一行,用null字符分隔原始行sort | uniq -c:对合并后的行排序并统计重复次数tr "\0" "\n":把合并的行重新拆分成原始的5行格式
关键注意点
- 一定要选择不会出现在文件内容中的分隔符,这里用
\0(null字符)是最安全的,因为普通文本文件几乎不会包含它;如果用其他字符串(比如|||),要确保你的文件里绝对没有这个串,否则会导致拆分错误。 - 如果需要保留原始顺序,优先用awk方案;如果追求简洁和大文件处理效率,用shell工具链方案。
内容的提问来源于stack exchange,提问作者user3746195
相关产品推荐
相关产品推荐

