![通配 shell 变量名](https://linux22.com/image/129710/%E9%80%9A%E9%85%8D%20shell%20%E5%8F%98%E9%87%8F%E5%90%8D.png)
我需要扩展一些与主题相关的 shell(不是环境)变量名称,例如,B2_...
其中...
可能是一个或多个不同的事物,例如、ACCOUNT_ID
等。ACCOUNT_KEY
RESPOSITORY
我不知道有多少个变量,也不知道它们是哪些。这就是我想知道的。
我希望能够迭代变量,B2...
而不必将每个单独的名称放入列表中,类似于我如何扩展文件名。
我使用 zsh 进行交互式会话,但 sh 或 bash 的解决方案也很好。
答案1
答案2
B2_
您可以使用关联数组 ( B2
),而不是使用名称以 开头的单个变量。例如
注:以下内容具体针对zsh
. ksh
并且bash
也有关联数组,但初始化和使用它们的语法不同(见下文)。
typeset -A B2
# initialise array
B2=(ACCOUNT_ID 12345 ACCOUNT_KEY 54321 REPOSITORY somewhere)
# two different ways of adding elements to the array
B2[FOO]=bar
B2+=(NAME fred)
for key val in ${(kv)B2}; do
echo "$key: $val"
done
该示例的输出将是:
ACCOUNT_KEY: 54321
FOO: bar
REPOSITORY: somewhere
ACCOUNT_ID: 12345
NAME: fred
您还可以使用以下命令打印整个数组(以适合在脚本或命令行中重复使用的形式)typeset -p
:
% typeset -p B2
typeset -A B2=( ACCOUNT_ID 12345 ACCOUNT_KEY 54321 FOO bar NAME fred REPOSITORY somewhere )
在 或 Bash 中的相同操作ksh
如下:
# initialise it
typeset -A B2
B2=([ACCOUNT_ID]=12345 [ACCOUNT_KEY]=54321 [REPOSITORY]=somewhere)
# add elements
B2[FOO]=bar
B2+=([NAME]=fred)
# get a list of the keys and use them as indexes to get the values
for key in "${!B2[@]}"; do
echo "$key: ${B2[$key]}"
done
# print the entire array
typeset -p B2
答案3
巴什有compgen -v
.
在 Bash 中,您可以列出以以下开头的变量名称B2
使用:
compgen -v B2
运行该命令会列出相同的变量,当您键入后跟时,这些变量可用作自动完成结果compgen -v text
$
text
然后按 Tab 键。 (您可能需要多次按 Tab 键才能显示所有内容。)您可以compgen -v
交互使用,但也可以在脚本中使用它。例如:
$ bash -c 'compgen -v SDK'
SDKMAN_CANDIDATES_DIR
SDKMAN_CURRENT_API
SDKMAN_DIR
SDKMAN_LEGACY_API
SDKMAN_PLATFORM
SDKMAN_VERSION
(当然,脚本可以位于文件中,而不是bash
作为-c
标志的操作数传递。)
的目的compgen
是执行命令完成。help compgen
有关它的一般信息,请参阅(在 Bash 中)的输出。尽管这可能会满足您的要求,但您可能会发现其他方法,例如中的参数扩展技术吉尔·奎诺的回答,更清楚地表达你在做什么。我真的不能说哪个更好,因为这取决于您正在做什么,也许还取决于您个人的风格偏好。
答案4
和zsh
:
for var (${(M)${(k)parameters}:#B2_*})
printf '$%s == %s\n' $var ${(P)var}
${(k)parameters}
是键$parameters
提供所有参数信息的特殊关联数组。${array:#B2_*}
删除从$array
扩展中,匹配 的元素B2_*
。对于(M)
(forM
atched),情况正好相反:保持匹配的元素。${(P)var}
(类似于bash
's${!var}
):扩展为名称存储在 中的参数的值$var
。
如果您只想要不导出的变量:
setopt extendedglob # for ^
for var (${(M)${(k)parameters[(R)^*export*]}:#B2_*})
printf '$%s == %s\n' $var ${(P)var}