替换文件中内外相同分隔符:将外层逗号替换为分号
替换CSV外层逗号为分号(保留引号内逗号)
问题描述
输入数据中外层分隔符为逗号,但部分带引号的字符串内部也包含逗号,需要仅将引号外部的逗号替换为分号,引号内的逗号保持不变,且带内层逗号的字符串可出现在任意位置。
原始输入示例:
"apple" , "tomato,potato", 100, 250, "banana"
期望输出:
"apple" ; "tomato,potato"; 100; 250; "banana"
可行解决方案
方案1:使用awk(兼容性好)
通过跟踪引号状态,精准替换非引号内的逗号:
awk -F '' '{ q = 0 for (i = 1; i <= NF; i++) { if ($i == "\"") q = !q # 切换引号状态标记 if ($i == "," && q == 0) $i = ";" # 仅替换非引号内的逗号 } print }' input.txt
方案2:使用gawk的FPAT特性(简洁直观)
利用gawk的FPAT自定义字段匹配规则,直接识别完整字段(含引号内的逗号),再用分号拼接输出:
gawk 'BEGIN { FPAT = "([^,]+)|(\"[^\"]+\")" # 匹配规则:无逗号的内容 或 带引号的完整字符串 OFS = "; " # 设置输出字段分隔符为分号+空格 } { for (i = 1; i <= NF; i++) { printf "%s%s", $i, (i < NF ? OFS : "\n") } }' input.txt
方案3:使用Perl正则
通过正则断言识别引号外的逗号:
perl -pe 's/(?<!")(,)(?!(?:"[^"]*"[^"]*)*[^"]*")/;/g' input.txt
验证结果
执行上述任意命令后,输出均与期望一致,无论带内层逗号的字符串处于数据哪个位置,都能正确保留内部逗号并替换外层分隔符。
内容的提问来源于stack exchange,提问作者Phantom
相关产品推荐
相关产品推荐

