BASH - 从 csv 文件的行创建数组,其中第一个条目是数组名称

Posted

技术标签:

【中文标题】BASH - 从 csv 文件的行创建数组,其中第一个条目是数组名称【英文标题】:BASH - Create arrays from lines of csv file, where first entry is array name 【发布时间】:2022-01-12 10:43:11 【问题描述】:

我正在学习在 Bash 中编写脚本。 我有一个 CSV 文件,其中包含下一行:

numbers,one,two,three,four,five
colors,red,blue,green,yellow,white
custom-1,a,b,c,d,e
custom+2,t,y,w,x,z

需要从这里创建数组,其中第一个条目是数组名称,例如。

number=(one,two,three,four,five)
colors=(red,blue,green,yellow,white)
custom-1=(a,b,c,d,e)
custom+2=(t,y,w,x,z)

这是我的脚本:

IFS=","
while read NAME VALUES ; do
    declare -a $NAME
    arrays+=($NAME)
    IFS=',' read -r -a $NAME <<< "$VALUES[0]"
done < file.csv

当我尝试使用仅包含两个第一个字符串(数字和颜色)的 csv 文件时,代码运行良好。如果我尝试使用数字、颜色、custom-1、custom-2,读取 csv 时会出错:

./script.sh: line 5: declare: `custom-1': not a valid identifier
./script.sh: line 7: read: `custom+2': not a valid identifier

据我所知,因为 bash 不允许在变量名中使用特殊字符。有什么办法可以避免吗?

【问题讨论】:

没有。您必须重命名变量。 Bash 也没有嵌套数组。而且不能把数组变成哈希值。 您的第一个数组应命名为numbers,而不是number。并且 bash 变量不能有任何名称。忘记custom-1custom+2,它们是无效的变量名,如错误消息所述。修改这些名称以使其成为有效的变量名称,或者使用例如计数器创建有效的数组名称,并将您感兴趣的名称存储为关联数组的键,其中值将是计数器。这样您就可以从第一列的文本中恢复真正的数组名称。 【参考方案1】:

由于您不能将 CSV 文件的第一列用作 bash 数组名称,因此一个选项是使用计数器生成有效名称(例如 arrayN)。如果您想使用第一列的值访问您的数据,您还需要将它们存储在具有相应计数器值的某个位置。关联数组 (declare -A names=()) 将是完美的。最后但同样重要的是,namerefs(declare -n arr=...,从 bash 4.3 开始可用)将方便存储和访问您的数据。示例:

declare -i cnt=1
declare -A names=()
while IFS=',' read -r -a line; do
  names["$line[0]"]="$cnt"
  declare -n arr="array$cnt"
  unset line[0]
  declare -a arr=( "$line[@]" )
  ((cnt++))
done < foo.csv

现在,要访问对应于条目custom+2 的值,首先获取相应的计数器值,声明一个指向相应数组的nameref,然后瞧:

$ cnt="$names[custom+2]"
$ declare -n arr="array$cnt"
$ echo "$arr[@]"
t y w x z

让我们声明一个函数以便于访问:

getdata () 
  local -i cnt="$names[$1]"
  local -n arr="array$cnt"
  [ -z "$2" ] && echo "$arr[@]" || echo "$arr[$2]"

然后:

$ getdata "custom+2"
t y w x z
$ getdata "colors"
red blue green yellow white
$ getdata "colors" 3
yellow

【讨论】:

declare -n 很有用,但需要 bash 4.3 @Fravadona 对。我为此添加了一条注释,谢谢。

以上是关于BASH - 从 csv 文件的行创建数组,其中第一个条目是数组名称的主要内容,如果未能解决你的问题,请参考以下文章

BASH - 如何从 CSV 文件中的列中提取数据并将其放入数组中?

使用 bash (sed/awk) 提取 CSV 文件中的行和列?

php 使用SplFileObject读取CSV文件。从CSV文件定义标题或管理标题行。返回数组中的行,标题值为

使用 Objective C 从 CSV 文件创建数组

在 Bash 中从文本文件创建数组

如何从 sql 创建 csv 文件获取逻辑应用程序上的行