我想产生一个shell脚本动态无功名称,以处理一组具有不同名称的文件中循环,如下所示:
#!/bin/bash
SAMPLE1='1-first.with.custom.name'
SAMPLE2='2-second.with.custom.name'
for (( i = 1; i <= 2; i++ ))
do
echo SAMPLE{$i}
done
我期望的输出:
1-first.with.custom.name
2-second.with.custom.name
但我得到:
SAMPLE{1}
SAMPLE{2}
是否有可能在飞行产生变种的名字呢?
你需要利用可变间接寻址:
SAMPLE1='1-first.with.custom.name'
SAMPLE2='2-second.with.custom.name'
for (( i = 1; i <= 2; i++ ))
do
var="SAMPLE$i"
echo ${!var}
done
从猛砸男子页 ,在“参数扩展”:
(!)“如果参数的第一个字符是一个感叹号,引入可变间接层bash使用从参数的其余部分作为变量的名称形成的变量的值;这个变量然后膨胀并值在替代的其余部分所使用的,而不是本身。这被称为间接膨胀参数的值“。
问题
您使用我的价值,如果它是一个数组索引。 它不是,因为SAMPLE1和SAMPLE2是独立变量,而不是一个数组。
此外,打电话时echo SAMPLE{$i}
你只是我的价值附加到单词“SAMPLE”。 您在此声明被提领的唯一的变量是$我 ,这就是为什么你得到了你做的结果。
的方式来解决这个问题
有解决这一主要有两种方式:
- 内插变量的多级解除引用,通过EVAL内建或间接变量扩展 。
- 迭代数组,或利用i作为索引到一个数组。
与EVAL取消引用
在这种情况下,以最简单的办法是使用eval:
SAMPLE1='1-first.with.custom.name'
SAMPLE2='2-second.with.custom.name'
for (( i = 1; i <= 2; i++ )); do
eval echo \$SAMPLE${i}
done
这将i的值追加到该变量的末尾,然后再处理所得到的线,扩大了内插的变量名称(例如SAMPLE1或SAMPLE2)。
与间接变量间接引用
对于这个问题的接受的答案是:
SAMPLE1='1-first.with.custom.name'
SAMPLE2='2-second.with.custom.name'
for (( i = 1; i <= 2; i++ ))
do
var="SAMPLE$i"
echo ${!var}
done
这在技术上是一个三个步骤的过程。 首先,它分配一个插值变量名称为VAR,然后取消引用存储在VAR变量名,最后扩展的结果。 它看起来干净了一点,有的人更熟悉的这个语法比EVAL,但结果是大致相同的。
迭代数组
可以简化两个环,并通过迭代数组,而不是使用可变内插扩展。 例如:
SAMPLE=('1-first.with.custom.name' '2-second.with.custom.name')
for i in "${SAMPLE[@]}"; do
echo "$i"
done
这增加了其他方法的好处。 特别:
- 你并不需要指定一个复杂的回路测试。
- 你可以通过$样品[$ i]语法访问单个数组元素。
- 你可以用$ {#示例}变量扩展元素的总数。
实际等效于原来的例子
这三种方法都将在原来的问题给出的例子中工作,但阵列解决方案提供最全面的灵活性。 选择哪一个最适合你手头上的数据。
您可以使用eval
如下图所示:
SAMPLE1='1-first.with.custom.name'
SAMPLE2='2-second.with.custom.name'
for (( i = 1; i <= 2; i++ ))
do
eval echo \$SAMPLE$i
done
还不如就我所知,他们的方式@ johnshen64说。 此外,您可以使用一个数组,像这样解决问题:
SAMPLE[1]='1-first.with.custom.name'
SAMPLE[2]='2-second.with.custom.name'
for (( i = 1; i <= 2; i++ )) do
echo ${SAMPLE[$i]}
done
请注意,您不需要使用数字作为指标SAMPLE[hello]
只会工作,以及
而不是一个独立的答案,只是除了米克尔的答案,我不能评论吻合。
您可以使用一个循环,+ =运算符,和这里的文件以及填充数组:
SAMPLE=()
while read; do SAMPLE+=("$REPLY"); done <<EOF
1-first.with.custom.name
2-second.with.custom.name
EOF
在bash 4.0,它是那样简单
readarray SAMPLE <<EOF
1-first.with.custom.name
2-second.with.custom.name
EOF