使用for循环seq分配动态bash变量名称 [英] Assigning dynamic bash variable names using a for loop seq

查看:119
本文介绍了使用for循环seq分配动态bash变量名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我正在尝试做某事,不确定是否可能.我有以下代码:

So I'm trying to do something, not sure if it's possible. I have the following code:

for i in {0..5}; do
    if [[ -f ./user$i ]]; then
        group$i=$(grep -w "group" ./user0|awk '{print $2}'|perl -lape 's/\s+//sg')

我要做的是为{0..5}的每个实例分配一个唯一变量,因此为每个变量名称指定group1 group2 group3 group4.然后,我将./user0更改为./user$i并根据我的序列创建一个动态变量列表. 这可能吗?尝试执行此操作时出现以下错误,但我不确定bash不喜欢自己实际执行了什么操作.

What I want to do is assign a unique variable for each instance of the {0..5} so group1 group2 group3 group4 for each variable name. Then I would change ./user0 to ./user$i and create a dynamic list of variables based on my sequence. Is this possible? I get the following error when trying to execute this and I'm unsure of what I have actually done that bash doesn't like.

test.sh:第16行:group0 = j:未找到命令

test.sh: line 16: group0=j: command not found

推荐答案

Kurt Stutsman 提供了正确的指针对问题的评论:使用Bash 数组 解决您的问题.

Kurt Stutsman provides the right pointer in a comment on the question: use Bash arrays to solve your problem.

这是一个简化的示例:

groups=() # declare an empty array; same as: declare -a groups
for i in {0..5}; do
  groups[i]="group $i"  # dynamically create element with index $i
done

# Print the resulting array's elements.
printf '%s\n' "${groups[@]}"

有关枚举数组${groups[@]}元素的其他方法,请参见此答案的底部.

See the bottom of this answer for other ways to enumerate the elements of array ${groups[@]}.

  • bash数组可以动态扩展(甚至可以是稀疏-元素索引不必是连续的)

  • bash arrays can be dynamically expanded (and can even be sparse - element indices need not be contiguous)

  • 因此,只需分配元素$i即可工作,而无需事先确定数组的大小.
  • Hence, simply assigning to element $i works, without prior sizing of the array.

请注意在数组下标中$i不需要 前缀的原因,因为数组下标是在算术上下文中求值的(相同计算$(( ... ))表达式的上下文).

Note how $i need not be prefixed with $ in the array subscript, because array subscripts are evaluated in an arithmetic context (the same context in which $(( ... )) expressions are evaluated).

关于您做错了什么:

group$i=...

Bash无法将

识别为变量赋值,因为-从字面上看 -group$i不是有效的标识符(变量名).

is not recognized as a variable assignment by Bash, because - taken literally - group$i is not a valid identifier (variable name).

因为不是,所以Bash继续解析,直到找到下一个shell元字符,然后将结果单词解释为要执行的 command ,在您的情况下,这会导致错误消息.

Because it isn't, Bash continues to parse until the next shell metacharacter is found, and then interprets the resulting word as a command to execute, which in your case resulted in error message group0=j: command not found.

如果由于某种原因,您不想使用 arrays 完全避免此问题,则可以 解决问题 :

If, for some reason, you don't want to use arrays to avoid this problem entirely, you can work around the problem:

通过涉及声明变量的内置 [命令](例如declarelocalexport),您可以强制Bash首先执行扩展 ,将group$i扩展为有效的变量名,然后再将其传递给内置变量.

By involving a variable-declaring builtin [command] such as declare, local, or export, you force Bash to perform expansions first, which expands group$i to a valid variable name before passing it to the builtin.

  • user2683246的答案通过使用declare(<或者,如果需要函数内部的局部变量,请按local)创建变量.

  • user2683246's answer demonstrates the next best approach by using declare (or, if local variables inside a function are desired, local) to create the variables.

Soren的答案使用export,但是仅当您要创建时才建议这样做环境变量对子进程可见 而不是单纯的 shell 变量.

Soren's answer uses export, but that is only advisable if you want to create environment variables visible to child processes rather than mere shell variables.

注意事项:使用此技术,请务必对RHS进行双引号 ,以获取全部价值;来说明:

Caveat: With this technique, be sure to double-quote the RHS in order to capture the full value; to illustrate:

 i=0; declare v$i=$(echo 'hi, there'); echo "$v0" # !! WRONG -> 'hi,': only UP TO 1ST SPACE

 i=0; declare v$i="$(echo 'hi, there')"; echo "$v0" # OK -> 'hi, there'


枚举上面创建的groups数组的其他方法:


Other ways to enumerate the groups array created above:

# Enumerate array elements directly.
for element in "${groups[@]}"; do
  echo "$element"
done

# Enumerate array elements by index.
for (( i = 0; i < ${#groups[@]}; i++ )); do
  echo "#$i: ${groups[i]}"
done

这篇关于使用for循环seq分配动态bash变量名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆