我想用数组在我的嘘脚本。
我的目标是创建一个包含值的数组a b c
并打印数组中的所有值。
我成功打印了每个数组,但未能打印数组中的所有值。
以下示例:
设置 arr 中的每个值:
n=1
eval arr$n=a
n=2
eval arr$n=b
n=3
eval arr$n=c
打印 arr 中的每个值:
n=1
eval echo \$arr$n
a
n=2
eval echo \$arr$n
b
n=3
eval echo \$arr$n
c
现在我想打印所有值,$arr
而不是a b c
我得到:
n="*"
eval echo \$arr$n
{*}*
值应该是a b c
.
答案1
有点晚了,但我在这里没有看到理想的sh
答案,所以我会插话。如果您不需要订阅,那么sh
有效做支持数组。它只支持它们作为空格分隔的字符串。您可以打印它们的全部内容,“推送”它们,或者迭代它们就可以了。
这是一些示例代码:
NAMES=""
NAMES="${NAMES} MYNAME"
NAMES="${NAMES} YOURNAME"
NAMES="${NAMES} THEIRNAME"
echo 'One at a time...'
for NAME in ${NAMES}; do
echo ${NAME};
done
echo 'All together now!'
echo ${NAMES}
哪个输出:
One at a time...
MYNAME
YOURNAME
THEIRNAME
All together now!
MYNAME YOURNAME THEIRNAME
现在,我说它不支持子脚本,但是通过一点点cut
魔法并使用空格作为适当的分隔符,您绝对可以模仿它。如果我们将其添加到上面示例的底部:
echo 'Get the second one'
echo ${NAMES} | cut -d' ' -f2
echo 'Add one more...'
NAMES="${NAMES} TOM"
echo 'Grab the third one'
echo ${NAMES} | cut -d' ' -f3
运行它,我们得到:
Get the second one
YOURNAME
Add one more...
Grab the third one
THEIRNAME
这正是我们所期望的!
但是,其中包含空格的字符串可能会导致问题,并且会完全破坏子脚本。
所以,更好的说法是:数组是不明显的,sh
并且处理带有空格的字符串数组很困难。如果您不需要这样做(例如,您想要部署到的主机名数组),那么它sh
仍然是完成这项工作的一个很好的工具。
答案2
sh
不支持大批,并且您的代码不会创建数组。它创建了三个变量arr1
, arr2
, arr3
。
要在类似 shell 中初始化数组元素ksh
,必须使用语法array[index]=value
。要获取数组中的所有元素,请使用${array[*]}
or ${array[@]}
。
尝试:
n=1
eval arr[$n]=a
n=2
eval arr[$n]=b
n=3
eval arr[$n]=c
n=1
eval echo \${arr[$n]}
n=2
eval echo \${arr[$n]}
n=3
eval echo \${arr[$n]}
n='*'
eval echo \${arr[$n]}
答案3
我同意正确的答案是寻找不同的方法。获取更好的 shell,切换到其他脚本语言(可能是 perl 或 python),或者重新考虑您的设计。但是,要获取名称以 开头的所有变量的值列表arr
,您可以使用
set | sed -n '/^arr[^=]*=/s///p'
这会将它们列出在单独的行中。要将它们全部放在一行上,请使用
echo $(set | sed -n '/^arr[^=]*=/s///p')
并不是说这会按字典顺序对它们进行排序,因此arr10
...arr19
将出现在arr1
和之间arr2
。 (如果您有名为maih1
, maih2
, …, maih10
, …, 的文件,也会发生同样的情况
maih19
。)如果您事先知道将拥有多少个数组元素,则可以通过使用前导零来解决此问题;例如,arr01
。arr02
,...,会让您达到99
。
set | sed …
PS如果任何变量值包含换行符,则该技巧将失败。