2011-06-27 14 views
8

Podczas zastępowania zewnętrznych poleceń w skrypcie powłoki użyłem tablicy, aby pozbyć się awk z NF.Jak oznaczyć tablicę w POSIX sh?

Teraz, odkąd przeniósł się z sh bash z POSIX, nie mogę dostać tablica oznaczone rację:

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

Używam OpenBSD, sh i ma dokładnie taki sam rozmiar jak ksh. Zmiana powyżej /bin/sh, wydaje się, że nie działa, co następuje:

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

Jak mogę zrealizować powyższy skrypt w /bin/sh? (Zauważ, że działa dobrze, jeśli wywołujesz bash z --posix, to nie jest to, czego szukam.)

+1

Na stronie: Nazwy zmiennych typu all-caps są złe. Zobacz konwencje nazw zmiennych środowiskowych na http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html, akapit czwarty, mając na uwadze, że zmienne środowiskowe i zmienne powłoki współdzielą przestrzeń nazw - a więc używają małych liter ponieważ zmienne lokalne zapobiegną przypadkowemu nadpisaniu przez system znaczenia. –

Odpowiedz

12

Tablice nie są częścią POSIX sh specification.

Istnieje wiele innych sposobów na znalezienie ostatniego przedmiotu. Kilka możliwości:

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

czyli

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

Minęło 5 lat. Jakakolwiek aktualizacja? –

1

Poniższy kod działa dla mnie za pomocą 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\): \$$#" 

Zauważ, że IFS jest ustawione na powierzchni i nie istnieją podwójne kwotowania około $RANGE.

+2

Działa to tylko dla elementów, które same nie zawierają białych znaków. Celem posiadania tablicy w twojej powłoce jest umożliwienie takich elementów. – chepner

2

Można użyć następującego projektu z Github, który implementuje tablicę zgodnej z POSIX, który działa we wszystkich muszli próbowałem: https://github.com/makefu/array

To nie jest bardzo wygodny w użyciu, ale okazało się, że dobrze działa na moje cele.