我可以将 csv 文件中的单行(已索引)导入到 zsh 数组中吗?

我可以将 csv 文件中的单行(已索引)导入到 zsh 数组中吗?

我想在 zsh 中逐行解析 csv 文件并将其存储在数组中(不带逗号)。是否可以将一行导入到 zsh 中的数组中,然后获取下一行?

问题是我使用的是一个大的 csv 文件,无法快速全部导入。我尝试使用下面的代码:

arr_csv=() 
while IFS= read -r line 
do
    arr_csv+=("$line")
done < import.csv

但由于文件很大,我想读取并存储一行(或访问一行)。

我知道我可以修改代码,这样

arr_csv=() 
while IFS= read -r line 
do
    arr_csv=("$line")
    # some modifications
done < import.csv

但如果我想循环该文件,如果我可以使用与 csv 文件中的行相对应的索引会更容易。此外,此方法不会删除分隔行的逗号。

答案1

我想说的是,这需要使用具有 CSV 支持的正确编程语言,例如perl/ python... 这里,而不是 shell。

但是,如果您必须使用zsh并且不介意删除单个单元格中的换行符和回车符,您可以使用 csvkitcsvformat将 csv 重新格式化为zsh可以read更轻松处理的格式:

< file.csv csvformat -SU3 -P'\' |
  while IFS=, read -A array; do
    typeset array # or anything with $array
  done

例如,对于这样的输入:

"foo bar ", "x,y", "blah""blah","new
line"
1,,2,"\\"

其中包括与 csv 相关的典型潜在陷阱的示例,其中给出:

array=( 'foo bar ' x,y 'blah"blah' newline )
array=( 1 '' 2 '\\' )

请注意,缺少-rsoread会被识别\为转义字符。不幸的是,虽然用, forcsvformat转义,但它被解释为行延续而不是转义换行符。<newline>\<newline>read

如果您知道输入中从未出现过的两个字符,则可以分别使用它们作为字段分隔符和记录分隔符。例如,可以是 ASCII记录分隔符单位分隔符控制字符在这里似乎很合适。

us=$'\x1f' rs=$'\x1e'
< file.csv csvformat -SU3 -D$us -M$rs -Q$rs |
  while IFS=$us read -rd$rs -A array; do
    something with $array
  done

这次,在相同的输入上给出:

array=( 'foo bar ' x,y 'blah"blah' $'new\nline' )
array=( 1 '' 2 '\\' )

相关内容