BASH - 从 csv 文件的行创建数组,其中第一个条目是数组名称
BASH - Create arrays from lines of csv file, where first entry is array name
我正在学习在 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 不允许在变量名中使用特殊字符,据我了解。有什么办法可以避免这种情况吗?
由于您不能将 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[]}"
local -n arr="array$cnt"
[ -z "" ] && echo "${arr[@]}" || echo "${arr[]}"
}
然后:
$ getdata "custom+2"
t y w x z
$ getdata "colors"
red blue green yellow white
$ getdata "colors" 3
yellow
我正在学习在 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 不允许在变量名中使用特殊字符,据我了解。有什么办法可以避免这种情况吗?
由于您不能将 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[]}"
local -n arr="array$cnt"
[ -z "" ] && echo "${arr[@]}" || echo "${arr[]}"
}
然后:
$ getdata "custom+2"
t y w x z
$ getdata "colors"
red blue green yellow white
$ getdata "colors" 3
yellow