2011-06-27 15 views
8

Trong khi thay thế các lệnh bên ngoài trong một kịch bản lệnh shell, tôi đã sử dụng một mảng để loại bỏ awk's NF.Làm thế nào để đánh dấu một mảng trong POSIX sh?

Bây giờ, kể từ khi tôi chuyển từ bash để POSIX sh, tôi không thể có được mảng đánh dấu đúng:

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

Tôi đang sử dụng OpenBSD, sh và nó có kích thước chính xác giống như ksh. Thay đổi ở trên để /bin/sh, có vẻ như những điều sau đây không làm việc:

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

Làm thế nào tôi có thể nhận ra các kịch bản nêu trên trong /bin/sh? (Lưu ý rằng nó hoạt động tốt nếu bạn gọi bash với --posix, đó không phải là những gì tôi tìm kiếm.)

+1

Bên cạnh: Tên biến toàn bộ có dạng không hợp lệ. Xem các quy ước về tên biến môi trường tại http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html, đoạn thứ tư, lưu ý rằng các biến môi trường và các biến shell chia sẻ một không gian tên - vì vậy hãy sử dụng các tên chữ thường cho các biến cục bộ của bạn sẽ ngăn việc vô tình ghi đè điều gì đó có ý nghĩa với hệ thống. –

Trả lời

12

Mảng không thuộc một phần của POSIX sh specification.

Có nhiều cách khác nhau để tìm mục cuối cùng. Một vài khả năng:

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

hay:

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

5 năm trôi qua. Bất kỳ bản cập nhật? –

1

Các mã sau đây làm việc cho tôi bằng cách sử dụng 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\): \$$#" 

Lưu ý rằng IFS được đặt thành một không gian và không có dấu ngoặc kép xung quanh $RANGE.

+2

Tính năng này chỉ hoạt động đối với các phần tử không chứa khoảng trắng. Điểm có một mảng trong trình bao của bạn là cho phép các phần tử như vậy. – chepner

2

Bạn có thể sử dụng các dự án sau đây từ Github, mà thực hiện một mảng POSIX-compliant, mà làm việc trong tất cả các vỏ tôi đã cố gắng: https://github.com/makefu/array

Nó không phải là rất thuận tiện để sử dụng, nhưng tôi thấy nó làm việc tốt cho mục đích của tôi.

Các vấn đề liên quan