如何在 POSIX shell 脚本中使用伪数组?

如何在 POSIX shell 脚本中使用伪数组?

如何在 POSIX shell 脚本中使用伪数组?

我想将 Bash 脚本中包含 10 个整数的数组替换为某物与 POSIX shell 脚本类似。

我设法遇到了Rich 的 sh (POSIX shell) 技巧,在截面上使用数组

我尝试过的:

save_pseudo_array()
{
    for i do
        printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"
    done
    echo " "
}

coords=$(save_pseudo_array "$@")
set -- 1895 955 1104 691 1131 660 1145 570 1199 381
eval "set -- $coords"

我不明白,这就是问题所在,如果有人能解释一下,非常感谢。

答案1

基本思想是用来set重新创建使用数组中的索引值的体验。因此,当您想要使用数组时,您可以set使用值来运行;那是

set -- 1895 955 1104 691 1131 660 1145 570 1199 381

然后您可以使用$1$2for来处理给定的值。

如果您需要多个数组,那么所有这些都没有多大用处。这就是saveandeval技巧的用武之地:里奇save函数1 处理当前位置参数并输出一个带有适当引用的字符串,然后可以使用该字符串来eval恢复存储的值。这样你就跑了

coords=$(save "$@")

将当前工作数组保存到 中coords,然后创建一个新数组,使用它,当您需要再次使用时coords,您eval可以:

eval "set -- $coords"

要理解这个示例,您必须考虑到您正在使用两个数组,一个是之前设置的值,您将其存储在 中coords,另一个数组包含 1895、955 等。代码片段本身并没有那么重要。就其本身而言,您需要在seteval行之间进行一些处理。如果稍后需要返回 1895, 955 数组,请在恢复之前先保存该数组coords

newarray=$(save "$@")
eval "set -- $coords"

这样您就可以$newarray稍后恢复。


1 定义为

save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}

答案2

这个想法是将任意字符串列表编码为标量变量,其格式稍后可用于重建列表或任意字符串。

 $ save_pseudo_array x "y z" $'x\ny' "a'b"
'x' \
'y z' \
'x
y' \
'a'\''b' \

$

当你坚持set --在前面时,它会生成 shell 代码来重建x,y z字符串列表并将其存储在$@数组中,你只需要eval使用它即可。

负责sed正确引用每个字符串('在第一行的开头、最后一行的末尾添加并用 替换所有's '\'')。

然而,这意味着为每个参数运行一个printf命令sed,因此效率相当低。这可以通过一种更直接的方式完成,只需调用一次 awk:

save_pseudo_array() {
  LC_ALL=C awk -v q=\' '
    BEGIN{
      for (i=1; i<ARGC; i++) {
        gsub(q, q "\\" q q, ARGV[i])
        printf "%s ", q ARGV[i] q
      }
      print ""
    }' "$@"
}

相关内容