如何用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
工作原理
这个逻辑的核心是通过状态标记区分两种空行:
prev_is_gender:标记上一行是否是Gender:开头的行。如果是,说明接下来的空行是记录分隔符,直接跳过不输出。first_record:避免在第一个记录开头输出多余的#####。- 当匹配到新记录的开头
Name:时,如果不是第一个记录,先输出#####作为分隔,再处理当前行。 - 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
相关产品推荐
相关产品推荐

