Unix下移除分号分隔CSV文件列值内的双引号
处理Unix环境下含内部额外双引号的非规范分号分隔CSV文件
问题描述
需处理一个90列的分号分隔(;)CSV文件,文件格式非规范:部分字段用双引号包裹,但字段内部存在额外双引号,且部分字段内容包含分号。
输入示例:
"AAAAA";"ABABDBDA";"ASDASDA"asads";"123";"456" "AAAAA";"ABABDBDA";"12322AAasd"asads";"123";"456" "Lmnop";"asdasads";"mer";"123;2343;asa"dwd";"456"
期望输出(将字段内的额外双引号替换为空格,保留字段结构):
"AAAAA";"ABABDBDA";"ASDASDA asads";"123";"456" "AAAAA";"ABABDBDA";"12322AAasd asads";"123";"456" "Lmnop";"asdasads";"mer";"123;2343;asa dwd";"456"
解决方案
方法1:使用Awk脚本(推荐,处理含分号的字段更可靠)
通过字符遍历+状态机,准确区分字段边界的双引号和内部额外双引号,将内部双引号替换为空格:
创建脚本fix_csv.awk:
BEGIN { FS = "" # 将每行按单个字符分割 } { in_quote = 0 # 标记是否处于字段的双引号内部 output_line = "" for (i = 1; i <= NF; i++) { if ($i == "\"") { if (in_quote) { # 下一个字符是分号则为字段结束引号,保留 if (i + 1 <= NF && $(i + 1) == ";") { output_line = output_line $i in_quote = 0 } else { # 字段内部的额外双引号,替换为空格 output_line = output_line " " } } else { # 字段起始引号,保留并标记进入引号内 output_line = output_line $i in_quote = 1 } } else { # 普通字符直接追加 output_line = output_line $i } } print output_line }
执行命令:
awk -f fix_csv.awk your_input.csv > fixed_output.csv
方法2:使用Sed命令(适合简单场景)
通过循环替换字段内部的双引号为空格,处理所有非字段边界的双引号:
sed -E ':loop; s/("[^";]*")(")([^";]*)/\1 \3/; t loop' your_input.csv > fixed_output.csv
该命令会反复匹配字段内的"内容"内容模式,将中间的双引号替换为空格,直到无匹配项为止。
内容的提问来源于stack exchange,提问作者Anand
相关产品推荐
相关产品推荐

