从 BASH 中最后一行的 CSV 列读取空字符串

从 BASH 中最后一行的 CSV 列读取空字符串

我使用以下gawk脚本从 csv 文件 file.csv 的第一列读取值。
我使用是gawk因为我不想忽略任何嵌入的逗号。

col=`gawk ' 
BEGIN {
FPAT="([^,]*)|(\"[^\"]*\")+"
}
{print $1 }' file.csv`

但是,我注意到如果空字符串/空格位于最后一行,则此方法会忽略它。

例如,如果 file.csv 如下:

col1,col2
"a,a","a,a1" 
"b","b1" 
,"c1"  

结果将是

col1
a,a
b 

代替

col1
a,a
b 

我可以做什么来解决这个问题?

谢谢你!

相关帖子:从 BASH 中的 CSV 文件读取空字符串

答案1

正如下面的评论中提到的你之前的问题,这与 CSV 或 awk 脚本无关,这与您如何保存命令的输出有关。

$ printf 'a\nb\n\n'
a
b

$ col=$(printf 'a\nb\n\n')
$ printf '%s' "$col"
a
b$

$ col=$(printf 'a\nb\n\n'; printf x)
$ printf '%s' "$col"
a
b

x$
$ col="${col%x}"
$ printf '%s' "$col"
a
b

$

请注意,通过上述内容,您将得到所有的保存在变量中的命令的输出,包括命令替换将删除的最终换行符。如果您也想删除最后一个换行符,请执行以下操作:

$ col="${col%$'\n'}"
$ echo "$col"
a
b

$ printf '%s' "$col"
a
b
$

x分两步删除和\n而不是执行单个步骤的原因col="$(col%$'\n'x}"是,如果命令没有产生输出或输出不以 a 结尾,那么操作将会失败,\n因为 then\nx不会存在于col

正确的:

$ col=$(printf 'a'; printf x)
$ col="${col%x}"
$ col="${col%$'\n'}"
$ printf '%s' "$col"
a$

错误的:

$ col=$(printf 'a'; printf x)
$ col="${col%$'\n'x}"
$ printf '%s' "$col"
ax$

要了解有关此问题的更多信息,请查看以下内容中的“命令替换”:

  1. POSIX 标准的Shell 执行环境部分它说:

shell 应通过在子 shell 环境中执行命令(请参阅 Shell 执行环境)并用命令的标准输出替换命令替换(命令文本加上“$()”或反引号)来扩展命令替换,删除替换末尾的一个或多个字符的序列。

  1. https://mywiki.wooledge.org/CommandSubstitution其中进一步讨论了该问题并提供了我上面使用的解决方法。

相关内容