使用for循环seq分配动态bash变量名称 [英] Assigning dynamic bash variable names using a for loop seq
问题描述
所以我正在尝试做某事,不确定是否可能.我有以下代码:
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:
通过涉及声明变量的内置 [命令](例如declare
,local
或export
),您可以强制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屋!