如何用sed或awk删除固定字符串后内容重复的行及其下一行?
文本去重方案:基于固定字符串后缀的行对去重
需求说明
需要处理文本文件,规则如下:
- 文件中含固定字符串的行(如示例中的1、3、5...行),仅判断从该固定字符串到行尾的内容是否重复
- 若某含固定字符串的行的上述后缀内容重复,则删除该行及其紧接的下一行,仅保留首次出现的该行和对应下一行
- 不含固定字符串的行(偶数行)的内容不参与重复判断,避免误删操作
示例文件格式:
somerandomtexthere fixedstring somepossibledupetext <- 1st line line to also delete if dupe right above <- 2nd line somerandomtexthere fixedstring somepossibledupetext <- 3rd line line to also delete if dupe right above <- 4th line
比如第1行和第9行的fixedstring后缀重复,则删除第9、10行,保留第1、2行。
问题回顾
此前尝试的awk命令(如下)会基于整行判断重复,导致不含固定字符串的行内容重复时误删,不符合需求:
awk '!(seen[$0]++&&(skip=1)||skip&&!(skip=0))' # 或 awk '!seen[$0]++||getline&&0'
解决方案:定制化awk脚本
可以用awk实现精准匹配,仅针对含固定字符串的行的后缀判断重复,脚本如下(将target="fixedstring"替换为你的实际固定字符串):
BEGIN { target = "fixedstring" } $0 ~ target { # 提取固定字符串到行尾的内容作为去重key key_start = index($0, target) key = substr($0, key_start) if (!(key in seen)) { # 首次出现,标记并打印当前行+下一行 seen[key] = 1 print $0 getline print $0 } else { # 重复出现,跳过当前行+下一行 getline } }
脚本逻辑说明
- 目标字符串定义:在
BEGIN块中指定需要匹配的固定字符串 - 匹配目标行:仅处理包含固定字符串的行
- 生成去重key:通过
index找到固定字符串的位置,用substr截取从该位置到行尾的内容作为判断重复的依据 - 判断与处理:
- 若key未出现过:标记为已见过,打印当前行,再读取并打印下一行
- 若key已出现过:直接读取下一行(跳过当前行和下一行)
验证效果
用示例文件测试时,脚本会保留第1、2行,删除重复的第3、4行,完全符合需求,且不会因不含固定字符串的行内容重复产生误删。
内容的提问来源于stack exchange,提问作者diggidre
相关产品推荐
相关产品推荐

