Оболочка: создать и назначить переменные внутри для цикла - PullRequest
0 голосов
/ 05 марта 2020

я делаю этот скрипт оболочки; это все oop, которые устанавливаются в переменную "a" каждый раз, в результате:

declare -a names=("one" "two" "three" "four")

    for item in "${names[@]}";
    do 
     a="$(cat <<-EOF
        {
          "NAME": "${item}_ABC",
          "CHANGED": "${item}_CHANGING",
          "VERSION": "${item}_GC",
        }
    EOF
    )"
    done
    echo $a

Моя цель состоит в том, чтобы изменить "a" динамически c имя переменной, которое будет $item_MYPREFIX

( конкатенация : $item + _MYPREFIX)

Так что мой код будет обобщенным c, что-то вроде этого:

for item in "${names[@]}";
do 
 $item_MYPREFIX="$(cat <<-EOF
    {
          "NAME": "${item}_ABC",
          "CHANGED": "${item}_CHANGING",
          "VERSION": "${item}_GC",
    }
EOF
)"
done

и я смогу отобразить каждую переменную: echo $one_MYPREFIX, echo $two_MYPREFIX ....

Конечно, это не работает alerady

Предложения, как это исправить?

Ответы [ 5 ]

2 голосов
/ 05 марта 2020

Использовать ассоциативный массив.

declare -A foo

for item in "${names[@]}";
do 
 foo[$item]="{
          \"NAME\": \"${item}_ABC\",
          \"CHANGED\": \"${item}_CHANGING\",
          \"VERSION\": \"${item}_GC\"
    }"
done
1 голос
/ 05 марта 2020

Попробуйте вот так

#!/bin/bash
for item in "${names[@]}"; do 
varname=${item}_MYPREFIX
declare $varname="
    {
          \"NAME\": \"${item}_ABC\",
          \"CHANGED\": \"${item}_CHANGING\",
          \"VERSION\": \"${item}_GC\",
    }
"
echo "${!varname}"
done

Но для этого лучше использовать массивы.

#!/bin/bash
declare -A array
names=("one" "two" "three" "four")
for item in "${names[@]}"; do 
indexname=${item}_MYPREFIX
array[$indexname]="
    {
          \"NAME\": \"${item}_ABC\",
          \"CHANGED\": \"${item}_CHANGING\",
          \"VERSION\": \"${item}_GC\",
    }
"
echo "${array[$indexname]}"
done
0 голосов
/ 05 марта 2020

Bash решение без eval, без ассоциативного массива и с использованием шаблона:

#!/usr/bin/env bash

declare -a names=("one" "two" "three" "four")

read -r -d '' template <<'EOF'
{
    "NAME": "%q_ABC",
    "CHANGED": "%q_CHANGING",
    "VERSION": "%q_GC"
}
EOF

for item in "${names[@]}"; do
  # shellcheck disable=SC2059 # format with a template variable
  printf -v "${item}_MYPREFIX" "$template" "$item" "$item" "$item" 
done

# Dump variables for debug
IFS=$'\n' read -r -d '' -a k < <(printf '%s_MYPREFIX\n' "${names[@]}")
typeset -p "${k[@]}"

Вывод:

declare -- one_MYPREFIX="{
    \"NAME\": \"one_ABC\",
    \"CHANGED\": \"one_CHANGING\",
    \"VERSION\": \"one_GC\"
}"
declare -- two_MYPREFIX="{
    \"NAME\": \"two_ABC\",
    \"CHANGED\": \"two_CHANGING\",
    \"VERSION\": \"two_GC\"
}"
declare -- three_MYPREFIX="{
    \"NAME\": \"three_ABC\",
    \"CHANGED\": \"three_CHANGING\",
    \"VERSION\": \"three_GC\"
}"
declare -- four_MYPREFIX="{
    \"NAME\": \"four_ABC\",
    \"CHANGED\": \"four_CHANGING\",
    \"VERSION\": \"four_GC\"
}"
0 голосов
/ 05 марта 2020

Это на самом деле не лучшая практика, но вы можете (в bash) сделать:

$ cat a.sh
#!/bin/bash

declare -a names=("one" "two" "three" "four")

for item in "${names[@]}"; do
        eval "read -d '' ${item}_MYPREFIX" << EOF
    {
          "NAME": "${item}_ABC",
          "CHANGED": "${item}_CHANGING",
          "VERSION": "${item}_GC",
    }
EOF
done

for item in "${names[@]}"; do
        k="${item}_MYPREFIX"
        echo "$k = ${!k}"
done
$ ./a.sh
one_MYPREFIX = {
          "NAME": "one_ABC",
          "CHANGED": "one_CHANGING",
          "VERSION": "one_GC",
    }
two_MYPREFIX = {
          "NAME": "two_ABC",
          "CHANGED": "two_CHANGING",
          "VERSION": "two_GC",
    }
three_MYPREFIX = {
          "NAME": "three_ABC",
          "CHANGED": "three_CHANGING",
          "VERSION": "three_GC",
    }
four_MYPREFIX = {
          "NAME": "four_ABC",
          "CHANGED": "four_CHANGING",
          "VERSION": "four_GC",
    }

Я считаю, что единственный там бешизм (помимо существования массивов, но у нескольких оболочек есть массивы) использование перенаправления ${!...}, но это только для вывода и не является действительно необходимым. Тем не менее, поскольку вы используете оболочку, которая поддерживает массивы, вы можете вообще этого не делать. Вместо создания переменной с именем «two_MYPREFIX» следует создать массив и сохранить это значение либо в индексе 2, либо использовать ассоциативный массив и сохранить его с индексом «два». Это было бы намного чище, чем использовать eval.

0 голосов
/ 05 марта 2020

heredocs не нужен, попробуйте это.

#!/usr/bin/env bash

declare -a names=("one" "two" "three" "four")
declare -a prefix=(foo bar baz more)

for item in "${!names[@]}"; do
   array+=("${prefix[$item]} = {
      "NAME": "${names[$item]}_ABC",
      "CHANGED": "${names[$item]}_CHANGING",
      "VERSION": "${names[$item]}_GC",
    }"
   )
done

printf '%s\n' "${array[@]}"

Вывод

foo = {
      NAME: one_ABC,
      CHANGED: one_CHANGING,
      VERSION: one_GC,
    }
bar = {
      NAME: two_ABC,
      CHANGED: two_CHANGING,
      VERSION: two_GC,
    }
baz = {
      NAME: three_ABC,
      CHANGED: three_CHANGING,
      VERSION: three_GC,
    }
more = {
      NAME: four_ABC,
      CHANGED: four_CHANGING,
      VERSION: four_GC,
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...