提问人:Uri 提问时间:11/17/2023 最后编辑:Uri 更新时间:11/17/2023 访问量:106
从 CSV 文件中提取前 2 个字段(可能包含逗号或引号)[重复]
Extract the first 2 fields from a CSV file (may contain commas or quotes) [duplicate]
问:
这篇文章在 5 天前经过编辑并提交审核。
我有一个包含 3 个或更多字段的 CSV 文件,我想按原样提取前 2 个字段,并将它们保存到一个新文件中。请注意,这些字段可能被引号或不引号引号,并且可能包含逗号或引号(加倍)。我想完全按原样提取前 2 个字段(无论是否引用),并忽略第三个字段和其他字段(如果是)。这应该从命令行完成。目前我有这个命令:
cat 1.csv | awk -F, '{print $1","$2}' > 2.csv
但是,如果字段中有逗号,则不起作用。
字段可以是空的(不包含任何内容,甚至不包含引号)。
(我还用awk检查了忽略CSV文件中的逗号,但那里的答案对我不起作用)
更新:这个问题是不同的,因为它要求CSV格式与原始格式相同 - 带引号或不带引号的字段。我有一个解决方案,我想提交。
答:
给定此输入文件,其中包含包含嵌入引号、逗号和换行符的带引号的字段:
$ cat file.csv
"foo,""bar""",2,3
1,"foo,bar",3
1,"foo,
bar",3
然后使用 GNU awk 5.3 或更高版本进行 CSV 处理:
$ awk --csv -v OFS=',' '{for (i=1; i<=NF; i++) { gsub(/"/,"\"\"",$i); if ($i ~ /[,\n"]/) $i="\"" $i "\"" } print $1, $2}' file.csv
"foo,""bar""",2
1,"foo,bar"
1,"foo,
bar"
读取输入时,CSV格式保护字段内容所需的引号将被剥离,因此我们必须在打印之前将它们添加回去,否则我们将得到以下输出:
$ awk --csv -v OFS=',' '{print $1, $2}' file.csv
foo,"bar",2
1,foo,bar
1,foo,
bar
这不是有效的 CSV。
另请参阅使用 awk 有效解析 CSV 的最可靠方法是什么?。
GoCSV 具有 select 子命令,该子命令允许使用从指定的(或管道传入的)CSV 中选择要保留(或排除)的列。GoCSV 是为许多现代平台预构建的。
从以下输入 CSV 开始:
Col1,Col2,Col3
"foo, bar",baz,baker
"Foo, Bar",Baz,baker
您可以直接在文件上调用 gocsv:
gocsv select -c 1,2 input.csv
或将 CSV 通过管道传递到:
cat input.csv | gocsv select -c 1,2
要获取:
Col1,Col2
"foo, bar",baz
"Foo, Bar",Baz
GoCSV 始终将第一行解释为标题(并使用标题,以便您可以根据需要按名称标注列)。如果原始文件没有标头,则可以从 cap 子命令开始添加临时标头,将其通过管道传递到 select 中,然后通过管道将其传输到 behead 子命令中以删除临时标头。
添加盖子:
echo \"foo, bar\",baz,baker\\n\"Foo, Bar\",Baz,Baker | gocsv cap -names Col1,Col2,Col3
Col1,Col2,Col3
"foo, bar",baz,baker
"Foo, Bar",Baz,Baker
... | gocsv select -c 1,2 | gocsv behead
"foo, bar",baz
"Foo, Bar",Baz
cap 子命令具有 -default-name 选项,但如果至少在显式列名上提供 -names 和 -names,它就无法工作。
下一个:分号作为 URL 查询分隔符
评论