我需要在 csv 文件中添加两个字段。csv 字段的分隔符是comma
,有些字段在双引号内。问题是,在双引号字段内,也可能找到逗号。如何用awk拆分?
这些字段来自 mongo 导出。这些字段的位置可能会改变,
样本输入 csv,
DateTime,Dealers,Locations,CallEndTime,TotalDuration
"2018-12-27 12:19:14","Dealer1,Dealer2,Dealer3","Gujarat",,67,,
"2018-12-27 12:19:14","Dealer1,Dealer2","Gujarat,Vadodara",,100,
样本输出 csv,
DateTime,Dealers,Locations,CallEndTime,TotalDuration
"2019-01-07 11:35:42","Dealer1,Dealer2,Dealer3","Gujarat","2019-01-07 11:36:51",69,,
"2018-12-27 12:19:14","Dealer1,Dealer2","Gujarat,Vadodara","2018-12-27 12:19:14,78",
awk 代码:
BEGIN { FSOFS=","}
NR==1 {
for (i=1; i<=NF; i++) {
f[$i] = i
}
}
NR>1 {
begSecs = mktime( gensub( /[":-]/, " ", "g", $(f["DateTime"]) ) )
endSecs = begSecs + $(f["TotalDuration"])
$(f["CallEndTime"]) = strftime("%Y-%m-%d %H:%M:%S", endSecs)
}
{print}
我不想将双引号内的逗号视为 FS,我已经看到这可以使用 FPAT 来完成,但我不知道如何在此处使用它,以防万一,
BEGIN { FPAT = "([^,]*)|(\"[^\"]+\")"}
NR==1 {
for (i=1; i<=NF; i++) {
f[$i] = i
}
}
NR>1 {
begSecs = mktime( gensub(/[":-]/," ","g",$(f["DateTime"])) )
endSecs = begSecs + $(f["TotalDuration"])
$(f["CallEndTime"]) = strftime("%Y-%m-%d %H:%M:%S", endSecs)
}
{print}
我不会
awk
用来解析 csv 文件,最好使用专用工具,例如使用 python csv 模块:输出.csv:
使用 csvkit >= 1.0.4(当前开发版本),您可以使用
csvsql
:你的第二个例子几乎可以工作。您只是缺少 a
,
作为输出分隔符 (OFS=","
) 并在新计算的日期周围加上双引号。这有效:对于给出的例子。
但是关于 csv 的内容比 awk 可以处理的要多得多。正如其他答案已经建议的那样,请使用正确理解 csv 格式的工具。
例如,要提取所有值并将分隔符逗号替换为
--
:示例输出:
FS
定义字段分隔符,即定义字段不是什么。FPAT
另一方面,它定义了字段是什么。顺便说一句,示例 input.csv 中的第一行有 6 个值,而第二行和标题行建议应该有 5 列。