列出带有前缀的变量,其中前缀存储在另一个变量中

Ang*_*elo 9 bash string variable

我试图列出具有特定前缀的所有变量,但该前缀是动态确定的。例如:

prefix=apple_
apple_one=a1
apple_two=a2
Run Code Online (Sandbox Code Playgroud)

如果我只是这样做:

echo ${!apple_@}
Run Code Online (Sandbox Code Playgroud)

我可以得到以apple_开头的变量名。但是,我想以某种方式使用变量前缀来做到这一点。我尝试过的一切都会导致糟糕的替代。例如我不能:

echo ${!${prefix}@}
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 8

Bash 不解析嵌套的变量扩展。你可以做你想做的事eval:构建 shell 片段${!apple_@},然后在你执行的命令中使用它eval

prefix=apple_
eval 'vars=(${!'"$prefix"'@})'
Run Code Online (Sandbox Code Playgroud)

确保prefix仅包含有效的标识符字符,否则代码段可能会导致任何结果。

eval通常需要使用动态计算名称的变量,但在这种特定情况下,有一种完全不同的方式来做同样的事情:使用完成系统。Bash 的完成系统甚至可以从脚本运行。在compgen每行内置列出一个完成,这是不明确的时候可以完工包含换行符,但这里不是这种情况-他们甚至不包含通配符,所以输出可以分割使用一个简单的不带引号的扩张。如果前缀包含在标识符中无效的字符,这将安全地不输出任何内容。

vars=($(compgen -v "$prefix"))
Run Code Online (Sandbox Code Playgroud)


cas*_*cas 5

你可以使用env | grep '^prefix'.

例如:

$ env | grep '^LESS'
LESSBINFMT=*u.
LESS=-MMqx4ij3
LESSOPEN=| /usr/bin/lesspipe %s
LESSCLOSE=/usr/bin/lesspipe %s %s
Run Code Online (Sandbox Code Playgroud)

如果您只需要值而不需要变量名称,请使用 awk:

$ env | awk -F= '/^LESS/ {print $2}'
*u.
-MMqx4ij3
| /usr/bin/lesspipe %s
/usr/bin/lesspipe %s %s
Run Code Online (Sandbox Code Playgroud)

(或仅打印 $1 作为变量名称)


更新2019-05-17

我通过赞成票回到了这个答案,并意识到有一个明显的改进:

typeset -p比 效果更好env,它输出所有变量,无论它们是否导出。例如:

typeset -p | awk '$3 ~ /^apple_/ { print $3 }'
Run Code Online (Sandbox Code Playgroud)

要使用变量而不是固定字符串:

prefix=apple_
typeset -p | awk '$3 ~ "^"pfx { print $3 }' pfx="$prefix" 
Run Code Online (Sandbox Code Playgroud)

或者只是导出 $prefix 以便它可以在 awk 的 ENVIRON 数组中使用:

export prefix=apple_
typeset -p | awk '$3 ~ "^"ENVIRON["prefix"] { print $3 }'
Run Code Online (Sandbox Code Playgroud)

注意:只需做一点工作,就可以使其与其他 shell(例如 ksh 或 zsh)一起使用,但重要的是要注意,typeset -p其他 shell 的输出格式不同,因此必须修改 awk 脚本以适应他们。

  • 如果未导出变量则不会。如果环境变量包含换行符,这可能会中断。 (2认同)