如何在POSIX中标记数组?

时间:2011-06-27 22:05:38

标签: arrays bash posix sh

在替换shell脚本中的外部命令时,我使用数组来摆脱awk的NF

现在,由于我从bash转移到POSIX sh,我无法将数组标记为正确:

#!/bin/bash
export RANGE="0 1 4 6 8 16 24 46 53"
RANGE=($RANGE)
echo arrayelements: $((${#RANGE[@]}))
LAST=$((${#RANGE[@]}-1))
echo "Last element(replace NF): ${RANGE[$LAST]}"

# ./foo
arrayelements: 9
Last element(replace NF): 53

我正在使用OpenBSD,sh和它的大小与ksh完全相同。 将上方更改为/bin/sh,似乎以下内容无效:

set -A "$RANGE"
set -- "$RANGE"

我怎样才能在/bin/sh中实现上述脚本? (请注意,如果使用--posix调用bash,它可以正常工作,这不是我想要的。)

3 个答案:

答案 0 :(得分:20)

数组不属于POSIX sh specification

还有其他各种方法可以找到最后一项。几种可能性:

#!/bin/sh
export RANGE="0 1 4 6 8 16 24 46 53"
for LAST_ITEM in $RANGE; do true; done
echo "Last element(replace NF): $LAST_ITEM"

或:

#!/bin/sh
export RANGE="0 1 4 6 8 16 24 46 53"
LAST_ITEM="${RANGE##* }"
echo "Last element(replace NF): $LAST_ITEM"

答案 1 :(得分:2)

您可以使用Github中的以下项目,它实现了一个符合POSIX的数组,该数组适用于我尝试的所有shell:https://github.com/makefu/array

使用起来不太方便,但我发现它适用于我的目的。

答案 2 :(得分:1)

以下代码适用于我Heirloom Bourne Shell

#!/usr/local/bin/bournesh
# cf. Heirloom Bourne Shell, 
#     http://freshmeat.net/projects/bournesh/
#     http://www.in-ulm.de/~mascheck/bourne/

# use a caret as a pipe symbol to make sure it's a Bourne shell
# cf. http://mywiki.wooledge.org/BourneShell
ls ^ cat 1>/dev/null 2>&1 || 
   { echo 'No true Bourne shell! ... exiting ...'; exit 1; }

IFS=' '
unset RANGE
RANGE="0 1 4 6 8 16 24 46 53"
export IFS RANGE
set -- $RANGE
echo arrayelements: $#
LAST=$#
eval echo "Last element\(replace NF\): \$$#"

请注意,IFS设置为空格,$RANGE周围没有双引号。