shell 脚本从数组中声明关联变量

shell script declare associative variables from array

我有数组键值对,由 space、

分隔
array=Name:"John" ID:"3234" Designation:"Engineer" Age:"32" Phone:"+123 456 789"

现在我想将上面的数组转换为关联变量,如下所示,

declare -A newmap
newmap[Name]="John"
newmap[ID]="3234"
newmap[Designation]="Engineer"
newmap[Age]="32"
newmap[Phone]="+123 456 789"

echo ${newmap[Name]}
echo ${newmap[ID]}
echo ${newmap[Designation]}
echo ${newmap[Age]}
echo ${newmap[Phone]}

我可以使用文件获取给定键的值,

declare -A arr
while IFS='=' read -r k v; do
   arr[$k]=$v;
done < "file.txt"
echo "${arr[name]}"

但我想使用数组而不是文件来实现相同的功能。

您可以在调用之前使用 sed 重新格式化输入数据 declare -A:

s='array=Name:"John" ID:"3234" Designation:"Engineer" Age:"32" Phone:"+123 456 789"'

declare -A "newmap=(
$(sed -E 's/" ([[:alpha:]])/" [/g; s/:"/]="/g' <<< "[${s#*=}")
)"

然后检查输出:

declare -p newmap

declare -A newmap=([ID]="3234" [Designation]="Engineer" [Age]="32" [Phone]="+123 456 789" [Name]="John" )

没有eval的版本:

array='Name:"John" ID:"3234" Designation:"Engineer" Age:"32" Phone:"+123 456 789"'
declare -A "newmap=($(perl -pe 's/(\w+):"/[]="/g' <<< "$array"))"
echo ${newmap[Phone]}
# output : +123 456 789

使用定义如下的变量 array

$ array='Name:"John" ID:"3234"   Designation:"Engineer"  Age:"32"   Phone:"+123 456 789"'

注释:

  • 假设属性“:”和值
  • 之间没有白色space
  • 假设 attribute/value 对
  • 之间可能存在可变数量的白色 space
  • 假设所有值都包含在一对双引号中

并假设希望解析此字符串并存储在名为 newmap ...

的数组中

我们可以使用 sed 将我们的字符串分成单独的行:

$ sed 's/" /"\n/g;s/:/ /g' <<< ${array}
Name "John"
ID "3234"
  Designation "Engineer"
 Age "32"
  Phone "+123 456 789"

然后我们可以将其提供给 while 循环来填充我们的数组:

$ unset newmap
$ typeset -A newmap

$ while read -r k v
do
    newmap[${k}]=${v//\"}         # strip off the double quote wrapper
done < <(sed 's/" /"\n/g;s/:/ /g' <<< ${array})

$ typeset -p newmap
declare -A newmap=([ID]="3234" [Name]="John" [Phone]="+123 456 789" [Age]="32" [Designation]="Engineer" )

并应用建议的(并稍加修改的)echo 语句:

$ (
echo "Name        - ${newmap[Name]}"
echo "ID          - ${newmap[ID]}"
echo "Designation - ${newmap[Designation]}"
echo "Age         - ${newmap[Age]}"
echo "Phone       - ${newmap[Phone]}"
)
Name        - John
ID          - 3234
Designation - Engineer
Age         - 32
Phone       - +123 456 789