скрипт оболочки объявляет ассоциативные переменные из массива - PullRequest
0 голосов
/ 23 апреля 2020

У меня есть пары ключ-значение массива, разделенные пробелом,

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]}"

Но я хочу реализовать те же функции, используя массив вместо файла.

Ответы [ 3 ]

1 голос
/ 23 апреля 2020

Версия без eval:

array='Name:"John" ID:"3234" Designation:"Engineer" Age:"32" Phone:"+123 456 789"'
declare -A "newmap=($(perl -pe 's/(\w+):"/[\1]="/g' <<< "$array"))"
echo ${newmap[Phone]}
# output : +123 456 789
1 голос
/ 23 апреля 2020

Работа с переменной array, которая была определена следующим образом:

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

ПРИМЕЧАНИЯ :

  • при условии, что нет пробел между атрибутом ':' и значением
  • при условии, что между парами атрибут / значение может существовать переменная величина пробела
  • при условии, что все значения заключены в пару двойных кавычек

И при условии, что вы хотите проанализировать эту строку и сохранить ее в массиве с именем newmap ...

Мы можем использовать sed, чтобы разбить нашу строку на отдельные строки как таковые:

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

Затем мы можем передать это в while l oop, чтобы заполнить наш массив:

$ 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
1 голос
/ 23 апреля 2020

Вы можете просто использовать sed для переформатирования входных данных перед вызовом declare -A:

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

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

Затем проверьте вывод:

declare -p newmap

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