我有一个 CSV 文件,但与相关问题不同,它有一些列包含带逗号的双引号字符串,例如
foo,bar,baz,quux
11,"first line, second column",13.0,6
210,"second column of second line",23.1,5
(当然它更长,并且引用逗号的数量不一定是 1 或 0,文本也不是可预测的。)文本也可能在双引号内包含(转义的)双引号,或者完全不包含双引号对于典型引用的字段。我们可以做的唯一假设是没有引用的换行符,因此我们可以使用
\n
简单地分割行。
现在,我想提取特定的列(例如第三列) - 例如,要打印在标准输出上,每行一个值。我不能简单地使用逗号作为字段分隔符(因此,例如使用
cut
);相反,我需要一些更复杂的东西。那会是什么?
注意:我在 Linux 系统上使用 bash。
这是一个快速而肮脏的 Python
csvcut
。 Python csv
库 已经了解各种 CSV 方言等的所有内容,因此您只需要一个薄包装器。
第一个参数应该表示您要提取的字段的索引,例如
csvcut 3 sample.csv
从(可能是引用的)CSV 文件中提取第三列
sample.csv
。
#!/usr/bin/env python3
import csv
import sys
writer=csv.writer(sys.stdout)
# Python indexing is zero-based
col = 1+int(sys.argv[1])
for input in sys.argv[2:]:
with open(input) as handle:
for row in csv.reader(handle):
writer.writerow(row[col])
要做的事情:错误处理、提取多列。 (本身并不难;使用
row[2:5]
提取第 3、4 和 5 列;但我懒得编写正确的命令行参数解析器。)
使用 GNU awk 来实现
FPAT
:
$ awk -v FPAT='[^,]*|"([^"]|"")*"' '{print $3}' file.csv
baz
13.0
23.1
请参阅 使用 awk 高效解析 CSV 的最可靠方法是什么?了解详细信息和替代方案。