如何使用awk或sed实现多行结构化文本转逗号分隔格式?
如何用awk或sed转换特定格式的文本文件?
当然可以!针对你这种按字段分组的文本格式,awk是最顺手的工具,它能轻松处理这种结构化的多行记录转换。下面给你两种可行的方案:
使用awk实现
awk天生擅长处理这种按规律分组的文本,我们可以每收集到一组NAME、ID、RANK就输出一行合并后的内容:
BEGIN { FS="\",\""; OFS="\",\"" } /"NAME"/ { name = $2 } /"ID"/ { id = $2 } /"RANK"/ { print "\""name"\",\""id"\",\""$2"\"" }
解释:
BEGIN { FS="\",\""; OFS="\",\"" }:设置输入字段分隔符为",",输出字段分隔符也设为同样的值,方便拆分和拼接字段。- 每匹配到
NAME行,就把第二个字段(也就是学生姓名)存到变量name里;匹配ID行时把ID存到id;匹配RANK行时,直接把三个变量按目标格式拼接输出,补上前后的双引号。
你可以直接用命令行执行:
awk 'BEGIN { FS="\",\""; OFS="\",\"" } /"NAME"/ {name=$2} /"ID"/ {id=$2} /"RANK"/ {print "\""name"\",\""id"\",\""$2"\""}' input.txt > output.txt
使用sed实现
sed虽然更擅长行级替换,但也能通过模式空间和保持空间的配合实现这个需求,只是写法会复杂一些:
sed -n ' /"NAME"/ {s/^"NAME","\(.*\)"/\1/;h;n; s/^"ID","\(.*\)"/\1/;H;n; s/^"RANK","\(.*\)"/\1/;H;g; s/\n/","/g;s/^\(.*\)$/"\1"/p }' input.txt > output.txt
解释:
-n:让sed只打印我们明确指定的内容,避免输出无关行。- 匹配
NAME行时,提取出姓名内容,放到保持空间暂存(h),然后读取下一行(n)。 - 匹配
ID行,提取ID内容,追加到保持空间(H),再读取下一行。 - 匹配
RANK行,提取排名内容,追加到保持空间,随后把保持空间的所有内容取到模式空间(g)。 - 把模式空间里的换行符替换成
",",再给整个内容前后加上双引号,最后打印处理后的行(p)。
两种方案都能完美实现你要的格式转换,个人更推荐awk方案,代码更易读、更易维护。
内容的提问来源于stack exchange,提问作者Ram
相关产品推荐
相关产品推荐

