我正在尝试将不同的数组写入 csv 文件 ($file) 列中。
每个数组都有相同数量的值。例如,arr1 和 arr2 各有 3 个值
arr1=( 23 45 34 )
arr2=( "abc,d" ef g )
我尝试了以下代码,但得到了错误的结果
for i in "${!arr1[@]}"; do
echo "${arr1[i]}, ${arr2[i]}" >> $file
done
我得到以下结果,其中 col1、col2 和 col3 是 3 列。
col1 col2 col3
23 "abc d"
45 ef
34 g
但期望的结果是
col1 col2
23 "abc,d"
45 ef
34 g
似乎“abc,d”中嵌入的彗差造成了问题。有人知道解决这个问题的方法或有更好的方法吗?
先感谢您!
答案1
从您的问题中不清楚您如何查看文件(也许使用电子表格程序?),但是 shell 可能会剥离数组定义中的引号:如果您希望以兼容 CSV 的方式处理嵌入的逗号,您应该将它们添加为文字引号,例如。
arr1=( 23 45 34 )
arr2=( \"abc,d\" ef g )
这样 shell 的内部表示看起来像
$ declare -p arr1 arr2
declare -a arr1=([0]="23" [1]="45" [2]="34")
declare -a arr2=([0]="\"abc,d\"" [1]="ef" [2]="g")
那么例如
for i in "${!arr1[@]}"; do
printf '%s,%s\n' "${arr1[i]}" "${arr2[i]}"
done > "$file"
结果是
$ cat "$file"
23,"abc,d"
45,ef
34,g
另一种选择是引用所有字段,例如。
arr1=( 23 45 34 )
arr2=( "abc,d" ef g )
for i in "${!arr1[@]}"; do
printf '"%s","%s"\n' "${arr1[i]}" "${arr2[i]}"
done > "$file"
给予
$ cat "$file"
"23","abc,d"
"45","ef"
"34","g"
答案2
此答案假设您的数据不包含文字选项卡。
首先为每个数组创建一个简单的列(带标题),然后使用 组合它们paste
,创建一个 TSV 数据流:
#!/bin/bash
arr1=( 23 45 34 )
arr2=( abc,d ef g )
paste <( echo col1; printf '%s\n' "${arr1[@]}" ) \
<( echo col2; printf '%s\n' "${arr2[@]}" )
其输出将读取
col1 col2
23 abc,d
45 ef
34 g
然后您可以使用 Miller 将其转换为正确引用的 CSV:
#!/bin/bash
arr1=( 23 45 34 )
arr2=( abc,d ef g )
paste <( echo col1; printf '%s\n' "${arr1[@]}" ) \
<( echo col2; printf '%s\n' "${arr2[@]}" ) | mlr --t2c cat
这会生成
col1,col2
23,"abc,d"
45,ef
34,g
... CSV 感知程序将读取为
第 1 列 | 列2 |
---|---|
23 | A B C D |
45 | 埃夫 |
34 | G |
支持 CSV 的电子表格程序也可能能够读取 TSV 数据,因此并不严格需要 Miller。