如何用Bash移除文本文件中连续重复的两行块?
连续两行重复块的去重方案
针对文本中连续出现的两行重复块(即连续四行里前两行与后两行完全一致),可以用以下两种方法处理,保留唯一的两行块并维持原有行顺序:
方法一:使用awk脚本(推荐,逻辑清晰易维护)
awk擅长处理多行文本的对比与缓存,以下脚本会缓存最近的两行,每读入新行时检查是否与缓存的两行重复,重复则跳过,否则输出缓存内容并更新缓存:
#!/usr/bin/awk -f NR == 1 { line1 = $0; next } NR == 2 { line2 = $0; next } { # 检查当前行与上一行是否和缓存的两行完全匹配 if ($0 == line2 && prev == line1) { # 匹配成功,跳过当前两行,更新缓存为当前这组重复块 line1 = $0 getline line2 = $0 next } # 不匹配则输出之前缓存的两行 print line1 print line2 # 更新缓存为上一行和当前行 line1 = prev line2 = $0 } # 记录上一行内容 prev = $0 # 处理文件末尾剩余的两行 END { print line1 print line2 }
使用方式
- 将上述代码保存为
dedup_pairs.awk - 执行命令:
awk -f dedup_pairs.awk input.txt
或者直接使用单行命令:
awk 'NR==1{l1=$0;next}NR==2{l2=$0;next}{if($0==l2&&prev==l1){l1=$0;getline;l2=$0;next}print l1;print l2;l1=prev;l2=$0}prev=$0END{print l1;print l2}' input.txt
方法二:使用sed脚本(纯文本流处理)
sed通过多行模式空间实现匹配,以下脚本会循环读取四行内容,匹配到重复的两行块时删除后两行,继续检查剩余内容:
:loop # 读取下一行(直到文件末尾) $!N $!N # 匹配前两行与后两行完全重复的情况 /\(.*\)\n\(.*\)\n\1\n\2/{ # 删除重复的后两行 s/\n\1\n\2// # 回到循环继续检查 b loop } # 输出模式空间的第一行 P # 删除模式空间的第一行,继续处理剩余内容 D
使用方式
- 将上述代码保存为
dedup_pairs.sed - 执行命令:
sed -f dedup_pairs.sed input.txt
或者直接使用单行命令:
sed ':loop;$!N;$!N;/\(.*\)\n\(.*\)\n\1\n\2/{s/\n\1\n\2//;b loop};P;D' input.txt
示例验证
假设input.txt内容如下:
foo bar foo bar baz boo baz boo test1 test2
处理后输出结果:
foo bar baz boo test1 test2
内容的提问来源于stack exchange,提问作者pmlk
相关产品推荐
相关产品推荐

