非GNU awk环境下无法合并CSV两列的技术求助
问题描述
现有格式为name,id,logindate的CSV文件,其中logindate字段格式为"July 15, YYYY HH:mm:ss"(字段内包含逗号),示例行如abc,123,"July 15, YYYY HH:mm:ss"。文件前5行是无需处理的表头及冗余信息,样例输入如下:
AuditReport asdf qwerty asdf name, id, logindate experiment,182002, "July 31, 2022 20:00:00" unit 1998,183065, "July 3, 2022 21:00:00" asdf, 202065, "May 25, 2022 20:00:00"
期望输出为跳过前5行后,移除logindate字段内的逗号,保持原有CSV格式:
experiment,182002, "July 31 2022 20:00:00" unit 1998,183065, "July 3 2022 21:00:00" asdf, 202065, "May 25 2022 20:00:00"
核心限制:生产环境仅支持非GNU版本awk,无法使用CSV解析器、其他语言或GNU awk的FPAT特性。此前尝试的多管道脚本无法正确合并因字段内逗号拆分的列,始终输出4列,无法得到预期结果。
之前尝试的脚本:
/usr/bin/env awk '{BEGIN{FS=","} NR>5 {print}' sample.csv | awk '{ gsub("\"", "") } { $1=$1 } 1' | awk '{ print $1, $2, $3" "$4 }' > test.csv
/usr/bin/env awk '{BEGIN{FS=","} NR>5 {print}' sample.csv | awk '{ gsub("\"", "") } { $1=$1 } 1' | awk '{ $3=$3" "$4, $4=""} 1' > test.csv
解决方案
直接用单条非GNU awk命令完成处理,无需多管道拆分,核心思路是只替换双引号内部的逗号,同时跳过前5行:
awk 'NR>5 { in_quote = 0 result = "" for (i=1; i<=length($0); i++) { c = substr($0, i, 1) if (c == "\"") { in_quote = !in_quote } if (in_quote && c == ",") { c = " " } result = result c } print result }' sample.csv > test.csv
原理说明
NR>5:直接跳过前5行冗余内容,无需额外管道处理。- 逐字符遍历每行:通过
in_quote标记是否处于双引号内部。 - 仅当处于双引号内且字符为逗号时,将其替换为空格;其他字符保持原样。
- 拼接处理后的字符并输出,完全保留原有CSV的列分隔符和格式。
这种方法避免了用逗号拆分列导致的字段断裂问题,直接精准处理目标逗号,适配非GNU awk环境。
内容的提问来源于stack exchange,提问作者pebble unit
相关产品推荐
相关产品推荐

