假设我们都读过https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html(具体来说,搜索间接扩张)。
这个问题的意思是,而不是这样做:
alpha_date=1563980822; alpha_hash=bfc1a9ad; alpha_url=http://example.com/bfc1a9ad; alpha_path=/build/alpha; alpha_status=failure; bravo_date=1563981822; bravo_hash=f76025c5; bravo_url=http://example.com/f76025c5; bravo_path=/build/alpha2; bravo_status=success; charlie_date=1563982822; charlie_hash=289f55fd; charlie_url=http://example.com/289f55fd; charlie_path=/build/charlie; charlie_status=success
for prefix in alpha bravo charlie; do
for suffix in date hash url path status; do
tempvar="${prefix}_${suffix}"
echo -n "$tempvar: ${!tempvar}"$'\t'
done
echo
done
这有效并输出:
alpha_date: 1563980822 alpha_hash: bfc1a9ad alpha_url: http://example.com/bfc1a9ad alpha_path: /build/alpha alpha_status: failure
bravo_date: 1563981822 bravo_hash: f76025c5 bravo_url: http://example.com/f76025c5 bravo_path: /build/alpha2 bravo_status: success
charlie_date: 1563982822 charlie_hash: 289f55fd charlie_url: http://example.com/289f55fd charlie_path: /build/charlie charlie_status: success
我想跳过创建tempvar
这样的东西:
for prefix in alpha bravo charlie; do
for suffix in date hash url path status; do
echo -n "${prefix}_${suffix} is ${!${prefix}_${suffix}}"$'\t'
done
echo
done
但当然我bad substitution
从 bash 中得到了一个错误。
有什么办法可以进行 bash“间接扩张”在“绳子”上?
答案1
如果您想设置变量,有很多方法(read "$a$b"
、printf -v "$a$b" ...
、declare "$a$b"=...
等)。
如果要读取该值,如果最终值为数字,则可以使用算术扩展来完成,因为算术扩展可以嵌套(但也请参阅在 Shell 算术评估中使用未经净化的数据的安全影响):
$ a=a b=cd acd=10
$ echo $(($a$b))
10
一般来说,bash 不支持嵌套替换。
当然,您的玩具示例可以在某种程度上被模仿:
for prefix in alpha bravo charlie; do
for suffix in date hash url path status; do
declare -p "${prefix}_${suffix}"
done
done
或者你可以尝试一下eval
:
eval "echo \"${prefix}_${suffix} is \${${prefix}_${suffix}}\""
答案2
您可以使用brace expansion
构建变量名称:
for i in {alpha,bravo,charlie}_{date,hash,url,path,status}; do
echo "$i is ${!i}"
done
答案3
如果使用ksh93
相反,你可以这样做:
data=(
[alpha]=(
[date]=1563980822
[hash]=bfc1a9ad
[url]=http://example.com/bfc1a9ad
[path]=/build/alpha
[status]=failure
)
[bravo]=(
[date]=1563981822
[hash]=f76025c5
[url]=http://example.com/f76025c5
[path]=/build/alpha2
[status]=success
)
[charlie]=(
[date]=1563982822
[hash]=289f55fd
[url]=http://example.com/289f55fd
[path]=/build/charlie
[status]=success
)
)
for prefix in alpha bravo charlie; do
for suffix in date hash url path status; do
printf '%s\n' "$prefix, $suffix, ${data[$prefix][$suffix]}"
done
done