我有这个shell脚本;这是一个循环,每次结果时都在变量“ 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
我的目的是如何通过动态变量名称$item_MYPREFIX
(并置:$item
+ _MYPREFIX
)
这样我的代码将是通用的,就像这样:
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
...。
当然,这不是天才的工作
建议,要遏制它?
答案 0 :(得分:2)
使用关联数组。
declare -A foo
for item in "${names[@]}";
do
foo[$item]="{
\"NAME\": \"${item}_ABC\",
\"CHANGED\": \"${item}_CHANGING\",
\"VERSION\": \"${item}_GC\"
}"
done
答案 1 :(得分:1)
尝试一下
#!/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
答案 2 :(得分:0)
不需要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,
}
答案 3 :(得分:0)
这实际上不是最佳实践,但是您可以(以bash方式)这样做:
p.id
我相信那里唯一的bashism(除了数组的存在,但是有几个shell有数组)是$ 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中,或者使用一个关联数组并以索引“ two”存储。这比使用${!...}
更干净。
答案 4 :(得分:0)
没有eval,没有关联数组且使用模板的Bash解决方案:
#!/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\"
}"