如何用Sed替换双引号外的所有逗号为换行符?
仅替换双引号外的逗号为换行符
要实现只替换双引号外的逗号为换行符、保留引号内逗号的需求,sed因缺乏状态跟踪能力很难直接处理这类场景,推荐用awk或Perl来实现。
问题重现
执行以下命令时:
echo 'this "ok,hi",hello,how' | sed "s/,/\n/g"
会把所有逗号(包括引号内的)都替换成换行,输出如下:
this "ok hi" hello how
解决方案1:使用awk(推荐)
这个方案能准确区分引号内外的内容,处理逻辑清晰:
echo 'this "ok,hi",hello,how' | awk -F'"' '{for(i=1;i<=NF;i++){if(i%2==1){gsub(/,/,"\n",$i)};printf "%s",$i}}'
输出结果:
this "ok,hi" hello how
如果需要同时去掉双引号,在后面追加sed处理即可:
echo 'this "ok,hi",hello,how' | awk -F'"' '{for(i=1;i<=NF;i++){if(i%2==1){gsub(/,/,"\n",$i)};printf "%s",$i}}' | sed 's/"//g'
输出结果:
this ok,hi hello how
逻辑说明
-F'"':将输入文本按双引号分割为多个字段- 循环遍历每个字段:
- 奇数索引的字段对应引号外的内容,用
gsub把其中的逗号替换为换行符 - 偶数索引的字段对应引号内的内容,直接保留原样输出
- 奇数索引的字段对应引号外的内容,用
- 最后用
printf拼接所有字段,完成文本重组
解决方案2:使用Perl
利用正则的正向预查来判断逗号是否在引号外:
echo 'this "ok,hi",hello,how' | perl -pe 's/(?=(?:[^"]*"[^"]*")*[^"]*$)/\n/g'
输出结果和awk方案一致,若要去掉引号同样追加sed 's/"//g'即可。
逻辑说明
正则(?=(?:[^"]*"[^"]*")*[^"]*$)是正向预查,确保当前逗号后面的双引号数量为偶数,说明该逗号处于引号外,才执行替换。
内容的提问来源于stack exchange,提问作者Tula
相关产品推荐
相关产品推荐

