Bash 如何从shell中确定CSV中的字段数?

Bash 如何从shell中确定CSV中的字段数?,bash,shell,csv,multiple-columns,counting,Bash,Shell,Csv,Multiple Columns,Counting,我有一个格式良好的CSV文件,可能有也可能没有标题行;可能有也可能没有引用的数据。我想使用shell确定其中的列数 现在,如果我能确定文件中没有带引号的逗号,那么以下方法似乎有效: x=$(tail -1 00-45-19-tester-trace.csv | grep -o , | wc -l); echo $((x + 1)) 但如果我不能做出这样的假设呢?也就是说,如果我不能假设逗号始终是字段分隔符怎么办?那我怎么做呢 如果有帮助,您可以假设不存在引号(即引号内字符串之间的“\”s);但

我有一个格式良好的CSV文件,可能有也可能没有标题行;可能有也可能没有引用的数据。我想使用shell确定其中的列数

现在,如果我能确定文件中没有带引号的逗号,那么以下方法似乎有效:

x=$(tail -1 00-45-19-tester-trace.csv | grep -o , | wc -l); echo $((x + 1))
但如果我不能做出这样的假设呢?也就是说,如果我不能假设逗号始终是字段分隔符怎么办?那我怎么做呢


如果有帮助,您可以假设不存在引号(即引号内字符串之间的“
\”
s);但最好也不要这样做。

如果您不能对数据做出任何乐观的假设,那么在Bash中就不会有简单的解决方案。解析带有可能嵌入的换行符和分隔符的通用CSV格式并不简单。您最好不要在Bash中编写,而是使用现有的正确的CSV解析。对于示例Python在其标准库中内置了一个

如果您可以假设没有嵌入的换行符和分隔符,那么使用awk拆分逗号就很简单:

awk -F, '{ print NF; exit }' input.csv
-F,
告诉awk使用逗号作为字段分隔符,自动
NF
变量是当前行上的字段数

如果希望允许嵌入分隔符,但可以假定没有嵌入双引号,则可以在管道连接到与前面相同的awk之前,使用简单过滤器消除嵌入分隔符:

head -n 1 input.csv | sed -e 's/"[^"]*"//g' | awk ...

请注意,这两个示例都使用第一行来决定字段的数量。如果输入有标题行,这应该可以很好地工作,因为标题不应包含嵌入的换行符,请在第一行中对字段进行计数,然后验证所有行的编号是否相同

 CNT=$(head -n1 hhdata.csv | awk -F ',' '{print NF}')

 cat hhdata.csv | awk -F ',' '{print NF}' | grep -v $CNT

不处理嵌入的逗号,但如果它们存在,将突出显示。

如果文件没有双引号,则使用以下命令:

awk -F"," '{ print NF }' filename| sort -u
awk -F, '{gsub(/"[^"]*"/,x);print NF}' filename | sort -u
如果文件的每一列都用双引号括起来,则使用以下命令:

awk -F"," '{ print NF }' filename| sort -u
awk -F, '{gsub(/"[^"]*"/,x);print NF}' filename | sort -u
“第一个字段”、“第二个字段、名称、with、逗号、in、it”、“第三个字段”。