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

如何用sed/awk替换记录分隔双空行,保留地址内双空行?

解决方案:区分记录分隔空行与Address字段内空行

首先看你的原始数据:

Name: ABC 
Address: 123, 4th Street,  
My County,
    
    
10009 Country. 
Age: 34 
Gender: Male
    
    
Name: DEF 
Address: 456, Orange Street,
    

North State,
    
45678 Country. 
Age: 68 
Gender: Female

核心问题是区分记录结束后的两个空行和Address字段内的空行——前者是分隔两个记录的,后者是Address内容的一部分。可以用awk来实现,因为它能轻松跟踪行的上下文状态。

具体实现

方法1:使用awk脚本

创建一个脚本文件(比如process_records.awk),内容如下:

BEGIN { prev_is_gender=0; first_record=1 }
/^Name:/ {
    if (!first_record) {
        print "#####"
    }
    first_record=0
    prev_is_gender=0
    print
    next
}
/^Gender:/ {
    print
    prev_is_gender=1
    next
}
/^$/ {
    if (prev_is_gender) {
        next
    } else {
        print
    }
    next
}
{
    prev_is_gender=0
    print
}

然后运行命令处理你的数据文件(假设文件名为data.txt):

awk -f process_records.awk data.txt

方法2:单行awk命令

如果不想写脚本,也可以用单行命令:

awk 'BEGIN{p=0;f=1}/^Name:/{if(!f)print"#####";f=0;p=0;print;next}/^Gender:/{print;p=1;next}/^$/{if(p)next;else print;next}{p=0;print}' data.txt

工作原理

这个逻辑的核心是通过状态标记区分两种空行:

  1. prev_is_gender:标记上一行是否是Gender:开头的行。如果是,说明接下来的空行是记录分隔符,直接跳过不输出。
  2. first_record:避免在第一个记录开头输出多余的#####。
  3. 当匹配到新记录的开头Name:时,如果不是第一个记录,先输出#####作为分隔,再处理当前行。
  4. Address字段内的空行,因为前后都不是Gender:行,会被正常保留输出。

输出结果

运行后你会得到:

Name: ABC 
Address: 123, 4th Street,  
My County,


10009 Country. 
Age: 34 
Gender: Male
#####
Name: DEF 
Address: 456, Orange Street,


North State,


45678 Country. 
Age: 68 
Gender: Female

可以看到,记录之间的两个空行被替换成了#####,而Address字段内的空行完全保留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 04:05:19