How to mark an array in POSIX sh?

When replacing external commands in a shell script, I used an array to get rid of awk NF .

Now, since I moved from bash to POSIX sh, I cannot get the array marked on the right:

 #!/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 

I use OpenBSD, sh and is the same size as ksh. Moving above to /bin/sh , it seems that the following does not work:

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

How could I implement the above script in /bin/sh ? (Note that it works fine if you call bash with --posix , this is not what I'm looking for.)

+8
arrays bash posix sh
source share
3 answers

Arrays are not part of the POSIX sh specification .

There are various ways to find the last item. A few possibilities:

 #!/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" 

or

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

You can use the following project from Github, which implements a POSIX-compatible array, which works in all the shells I tried: https://github.com/makefu/array

It is not very convenient to use, but I found that it works well for my purposes.

+2
source share

The following code works for me using the 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 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\): \$$#" 

Note that IFS set to a space and there are no double quotes around $RANGE .

+1
source share

All Articles