基于AWK实现长重复字符串匹配及完整段落返回的技术需求
优化AWK脚本实现跨段落重复长字符串检测并返回对应段落
需求明确
- 检测目标:长度大于6个字符的重复字符串(原需求为>7,现更新为>6)
- 重复场景支持:
- 同段落内非重叠的重复出现
- 不同段落间的跨段重复
- 输出要求:返回所有包含该重复串的完整段落(段落以空行为分隔符)
- 现有问题:原AWK脚本仅能识别单段落内的重复串,无法处理跨段落匹配,需优化以适配大文本文件处理
优化后的AWK脚本
BEGIN { RS = "" # 以空行作为段落分隔符 min_len = 7 # 对应>6的长度要求,子串长度至少7 } # 处理每个段落,记录所有符合长度的子串及其所属段落索引 { para_idx = NR para = $0 # 存储当前段落内已识别的子串,避免同段落内重复记录 delete seen_substr len = length(para) # 遍历所有可能的子串起始位置 for (i=1; i <= len - min_len + 1; i++) { # 遍历子串长度,从min_len到剩余字符数 for (j=min_len; j <= len - i + 1; j++) { substr_val = substr(para, i, j) if (!seen_substr[substr_val]) { # 检查当前子串在本段落内是否重复出现(非重叠) count = 0 pos = 1 while ((pos = index(substr(para, pos), substr_val)) != 0) { count++ pos += j # 跳过当前子串长度,避免重叠匹配 } if (count >= 2) { # 同段落内重复,记录该段落 substr_para[substr_val] = substr_para[substr_val] " " para_idx seen_substr[substr_val] = 1 } else { # 仅出现一次,先记录段落索引 if (!(substr_val in substr_para)) { substr_para[substr_val] = para_idx } else { # 该子串已在其他段落出现,追加当前段落索引 substr_para[substr_val] = substr_para[substr_val] " " para_idx } } } } } # 保存所有段落内容,方便后续输出 para_content[para_idx] = para } END { # 遍历所有子串,找出出现于多个段落或同段落内重复的情况 for (s in substr_para) { split(substr_para[s], para_list, " ") # 去重段落列表(同段落可能被多次记录,比如子串多次出现) delete unique_paras for (p in para_list) { unique_paras[para_list[p]] = 1 } # 如果段落数>=2,或者同段落内重复(段落数=1但子串在该段落出现多次) if (length(unique_paras) >= 2 || (length(unique_paras) == 1 && (split(substr_para[s], tmp) >= 2))) { print "重复字符串: '" s "'" print "包含该串的段落:" for (p in unique_paras) { print "------------------------" print para_content[p] print "------------------------" } print "" } } }
测试案例验证
案例1:梵语跨段落重复
输入文本:
सर्वभूतहिते रताः Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua सर्वभूतहिते रताः ut enim ad minim veniam
输出会包含两个段落,因为सर्वभूतहिते रताः(长度远大于6)跨段落重复。
案例2:英文单段落内重复
输入文本:
The weather is extremely hot, and extremely dry. I can't wait for the rain to come.
输出会返回该段落,因为extremely(长度8>6)在段落内非重叠重复出现。
案例3:跨段落带空格的重复串
输入文本:
Today is a extre mely good day, full of sunshine. I went to the park and played with friends. extre mely weather makes everyone feel happy.
输出会返回第一和第三段落,因为extre mely(长度7>6)跨段落重复。
脚本说明
- 用
RS = ""实现空行分隔段落,适配大文本的段落识别 - 对每个段落生成所有符合长度要求的子串,检查同段落内的非重叠重复情况
- 用数组记录每个子串对应的段落索引,最终筛选出重复出现的子串并输出对应段落
- 针对大文本优化:仅记录必要的子串和段落索引,避免冗余计算
内容的提问来源于stack exchange,提问作者shantanuo
相关产品推荐
相关产品推荐

