通配 shell 变量名

通配 shell 变量名

我需要扩展一些与主题相关的 shell(不是环境)变量名称,例如,B2_...其中...可能是一个或多个不同的事物,例如、ACCOUNT_ID等。ACCOUNT_KEYRESPOSITORY

我不知道有多少个变量,也不知道它们是哪些。这就是我想知道的。

我希望能够迭代变量,B2...而不必将每个单独的名称放入列表中,类似于我如何扩展文件名。

我使用 zsh 进行交互式会话,但 sh 或 bash 的解决方案也很好。

答案1

使用 参数扩展

$ foobar_1=x foobar_2=y foobar_3=z
$ for v in "${!foobar_@}"; do echo "$v"; done

输出 :

foobar_1
foobar_2
foobar_3

'取消引用':

$ for v in "${!foobar_@}"; do echo "${!v}"; done

输出²:

x
y
z

答案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)(for Matched),情况正好相反:保持匹配的元素。
  • ${(P)var}(类似于bash's ${!var}):扩展为名称存储在 中的参数的值$var

如果您只想要不导出的变量:

setopt extendedglob # for ^
for var (${(M)${(k)parameters[(R)^*export*]}:#B2_*})
  printf '$%s == %s\n' $var ${(P)var}

相关内容