一个简单的问题,我可以在sh
下使用数组,而不是bash
zsh
或其他任何东西。
ARRAYNAME=(value1 value2 .... valueN)
上面的命令仅适用于bash
。sh
还有其他选择吗?
我试图搜索这样的问题,但没有找到纯sh的答案。
POSIX sh 中每个堆栈帧只有一个"数组",那就是当前范围的参数列表。
您可以重置它:
set -- "first item" "second item"
。附加到它:
set -- "$@" "new item"
。从前面删除内容:
echo "First item is $1"
shift
echo "First item is $1"
。并通过跳转到新的函数作用域来创建一个新的函数:
someFunc() {
echo "The argument list for this function is:" >&2
printf ' - %sn' "$@"
}
someFunc argOne argTwo
。但是因为一次只有一个范围,所以它非常有限。
如果没有限制,ksh(以及后来的bash 和其他人)就没有理由添加任何其他形式的数组!
一种技巧是滥用字符串,就好像它们是数组一样,当您需要索引它们时将它们拆分为函数参数:
s='A|B|C|D' # specify your "array" as a string with a sigil between elements
IFS='|' # specify separator between elements
set -f # disable glob expansion, so a * doesn't get replaced with a list of files
getNth() { shift "$(( $1 + 1 ))"; printf '%sn' "$1"; }
getLast() { getNth "$(( $(length "$@") - 1 ))" "$@"; }
length() { echo "$#"; }
length $s # emits 4
getNth 0 $s # emits A
getNth 1 $s # emits B
getLast $s # emits D
当然,这意味着您需要保留值中不存在的符号字符。
作为一个与上述类似操作的第三方 shell 库(将"数组"编码为字符串,并在这些字符串中存储和检索内容),但具有转义/取消转义支持,因此不需要符号,您也可以看看 https://github.com/makefu/array/blob/master/array。也就是说,上面的代码为每次查找调用外部可执行文件 - 通过使用 POSIX sh 为每个操作调用sed
和awk
副本的额外运行时开销,您将很快失去在 shell 启动时间中获得的任何收益。