sh + 如何在 sh 脚本中使用数组来打印数组中的所有值

sh + 如何在 sh 脚本中使用数组来打印数组中的所有值

我想用数组在我的脚本。

我的目标是创建一个包含值的数组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。)如果您事先知道将拥有多少个数组元素,则可以通过使用前导零来解决此问题;例如,arr01arr02,...,会让您达到99

set | sed …PS如果任何变量值包含换行符,则该技巧将失败。

相关内容