당신은 본쉘 (다른 많은 조개 등을 제한 할 가정 csh
, tcsh
, rc
, es
또는 fish
지원 배열하지만 껍질 같은 Bourne 씨에 동시에 호환 스크립트를 작성하고 완전히 다른 및 통역과 마찬가지로 사람들은 까다 롭고 일반적으로 무의미 호환되지 않는 언어), 구현 간에는 상당한 차이가 있습니다.
배열을 지원하는 Bourne과 같은 쉘은 다음과 같습니다.
ksh88
(배열을 구현하는 최초의 하나가, ksh88 여전히 같은 발견 ksh
은 또한의 기초가 어디 대부분 기존의 상용 유닉스에서 sh
)
- 배열은 1 차원입니다
- 배열로 정의되어 있습니다
set -A array foo bar
또는 set -A array -- "$var" ...
당신은 보장 할 수없는 경우 그 $var
이 시작되지 않습니다 -
또는 +
.
- 배열 인덱스는에서 시작
0
합니다.
- 개별 배열 요소는로 지정됩니다
a[1]=value
.
- 배열이 드물다. 즉
a[5]=foo
경우에도 작동 a[0,1,2,3,4]
설정되지 않은 및 해제를 떠날 것이다.
${a[5]}
indice 5의 요소에 액세스하기 위해 (배열이 드문 경우 반드시 여섯 번째 요소는 아닙니다). 는 5
산술 표현식이있을 수있다.
- 배열 크기와 아래 첨자는 4096으로 제한됩니다.
${#a[@]}
배열에서 할당 된 요소의 수입니다 (가장 큰 할당 된 지표는 아님).
- 지정된 첨자 목록을 알 수있는 방법은 없습니다 (4096 개 요소를 개별적으로 테스트하는 것 제외
[[ -n "${a[i]+set}" ]]
).
$a
와 동일합니다 ${a[0]}
. 즉, 배열은 스칼라 변수에 추가 값을 제공하여 확장합니다.
pdksh
그리고 파생 상품 (이것은 ksh
때로는 sh
여러 BSD 의 기초이며 ksh93 소스가 해제되기 전에 유일한 오픈 소스 ksh 구현이었습니다) :
주로 좋아 ksh88
하지만 참고하십시오 :
- 일부 오래된 구현은을 지원하지 않았습니다
set -A array -- foo bar
( --
필요하지 않았습니다).
${#a[@]}
가장 큰 배정 된 지표의 지수에 1을 더한 것입니다. ( a[1000]=1; echo "${#a[@]}"
배열에 요소가 하나만 있어도 1001을 출력합니다.
- 최신 버전에서는 배열 크기가 더 이상 제한되지 않습니다 (정수 크기 제외).
- 최근 버전
mksh
에서 영감을 몇 가지 추가 연산자를 가지고 bash
, ksh93
또는 zsh
라 과제처럼 a=(x y)
, a+=(z)
, ${!a[@]}
할당 된 인덱스의 목록을 얻을 수 있습니다.
zsh
. zsh
배열은 일반적으로 더 나은 디자인과 최고의 가지고 있습니다 ksh
및 csh
배열을. 그것들은 비슷 ksh
하지만 큰 차이점이 있습니다.
- 인덱스는 0이 아닌 1에서 시작합니다 (
ksh
에뮬레이션 제외 ). Bourne 배열 ( zsh
$ argv 배열로 표시 되는 위치 매개 변수 $ @ ) 및 csh
배열 과 일치 합니다.
- 그것들은 정규 / 스칼라 변수와는 별개의 유형입니다. 운영자는 일반적으로 기대하는 것처럼 다르게 적용됩니다.
$a
는 같지 ${a[0]}
않지만 배열의 비어 있지 않은 요소로 확장됩니다 ( "${a[@]}"
에서와 같은 모든 요소에 대해 ksh
).
- 그것들은 희소 배열이 아닌 일반 배열입니다.
a[5]=1
작동하지만 1에서 4까지의 모든 요소가 할당되지 않은 경우 빈 문자열을 할당합니다. 따라서 ${#a[@]}
( ${#a}
ksh에서 indice 0의 요소 크기 와 동일 )는 배열의 요소 수 와 가장 큰 할당 된 indice입니다.
- 연관 배열이 지원됩니다.
- 배열로 작업하기위한 수많은 연산자가 지원되며 여기에 나열하기에는 너무 큽니다.
- 로 정의 된 배열
a=(x y)
. set -A a x y
또한 작동하지만 set -A a -- x y
ksh 에뮬레이션이 아닌 경우 지원되지 않습니다 ( --
zsh 에뮬레이션에는 필요하지 않음).
ksh93
. (여기서는 최신 버전을 설명합니다). FOSS로 출시 된 지금은 ksh93
오랫동안 실험으로 간주 된 실험 이 점점 더 많은 시스템에서 발견 될 수 있습니다. 예를 들어, /bin/sh
(Bourne 쉘을 대체 /usr/xpg4/bin/sh
한 POSIX 쉘은 여전히을 기반으로합니다 ksh88
) 및 ksh
의 Solaris 11
입니다. 그 배열은 ksh88을 확장하고 향상시킵니다.
a=(x y)
는 배열을 정의하는 데 사용될 수 있지만 a=(...)
복합 변수 ( a=(foo=bar bar=baz)
) 를 정의하는 데에도 사용 되므로 a=()
모호하며 배열이 아닌 복합 변수를 선언합니다.
- 배열은 다차원 (
a=((0 1) (0 2))
)이며 배열 요소는 복합 변수 ( a=((a b) (c=d d=f)); echo "${a[1].c}"
) 일 수도 있습니다 .
a=([2]=foo [5]=bar)
구문은 한 번에 스파 스 배열을 정의 할 수 있습니다.
- 크기 제한이 해제되었습니다.
- 의 범위는
zsh
아니지만 배열을 조작하는 데 지원되는 많은 연산자가 있습니다.
"${!a[@]}"
배열 인덱스 목록을 검색합니다.
- 연관 배열도 별도의 유형으로 지원됩니다.
bash
. bash
GNU 프로젝트의 쉘입니다. 그것은으로 사용되는 sh
OS / X 및 일부 GNU / Linux 배포판의 최신 버전에. bash
배열은 주로 및의 ksh88
일부 기능이있는 배열을 에뮬레이션 합니다 .ksh93
zsh
a=(x y)
지원됩니다. 지원 set -A a x y
되지 않습니다 . a=()
빈 배열을 만듭니다 (에 복합 변수 없음 bash
).
"${!a[@]}"
지수 목록.
a=([foo]=bar)
ksh93
및 에서 제공되는 구문뿐만 아니라 다른 구문도 지원합니다 zsh
.
- 최신
bash
버전은 또한 연관 배열을 별도의 유형으로 지원합니다.
yash
. 비교적 최신의 깨끗한 멀티 바이트 인식 POSIX sh 구현입니다. 널리 사용되지 않습니다. 배열은 다음과 비슷한 또 다른 깨끗한 API입니다.zsh
- 배열이 희박하지 않습니다
- 배열 인덱스는 1에서 시작
- 로 정의 및 선언
a=(var value)
array
내장으로 삽입, 삭제 또는 수정 된 요소
array -s a 5 value
해당 요소가 사전에 지정되지 않은 경우 5 번째 요소 를 수정하면 실패합니다.
- 배열의 요소 수는
${a[#]}
, ${#a[@]}
리스트와 요소의 크기 인.
- 배열은 별도의 유형입니다.
a=("$a")
요소를 추가하거나 수정하기 전에 스칼라 변수를 배열로 재정의 해야 합니다.
- 로 호출되면 배열이 지원되지 않습니다
sh
.
따라서 배열 지원을 감지하는 것을 볼 수 있습니다.
if (unset a; set -A a a; eval "a=(a b)"; eval '[ -n "${a[1]}" ]'
) > /dev/null 2>&1
then
array_supported=true
else
array_supported=false
fi
그 배열을 사용할 수있을만큼 충분하지 않습니다. 배열을 전체 및 개별 요소로 할당하기 위해 래퍼 명령을 정의하고 희소 배열을 만들지 않도록해야합니다.
처럼
unset a
array_elements() { eval "REPLY=\"\${#$1[@]}\""; }
if (set -A a -- a) 2> /dev/null; then
set -A a -- a b
case ${a[0]}${a[1]} in
--) set_array() { eval "shift; set -A $1"' "$@"'; }
set_array_element() { eval "$1[1+(\$2)]=\$3"; }
first_indice=0;;
a) set_array() { eval "shift; set -A $1"' -- "$@"'; }
set_array_element() { eval "$1[1+(\$2)]=\$3"; }
first_indice=1;;
--a) set_array() { eval "shift; set -A $1"' "$@"'; }
set_array_element() { eval "$1[\$2]=\$3"; }
first_indice=0;;
ab) set_array() { eval "shift; set -A $1"' -- "$@"'; }
set_array_element() { eval "$1[\$2]=\$3"; }
first_indice=0;;
esac
elif (eval 'a[5]=x') 2> /dev/null; then
set_array() { eval "shift; $1=("'"$@")'; }
set_array_element() { eval "$1[\$2]=\$3"; }
first_indice=0
elif (eval 'a=(x) && array -s a 1 y && [ "${a[1]}" = y ]') 2> /dev/null; then
set_array() { eval "shift; $1=("'"$@")'; }
set_array_element() {
eval "
$1=(\${$1+\"\${$1[@]}"'"})
while [ "$(($2))" -ge "${'"$1"'[#]}" ]; do
array -i "$1" "$2" ""
done'
array -s -- "$1" "$((1+$2))" "$3"
}
array_elements() { eval "REPLY=\${$1[#]}"; }
first_indice=1
else
echo >&2 "Array not supported"
fi
그리고 당신은 배열을 가진 요소에 액세스 "${a[$first_indice+n]}"
하여, 전체 목록 "${a[@]}"
과 래퍼 함수를 사용 ( array_elements
, set_array
, set_array_element
) (에서 배열의 요소 수를 얻기 위해 $REPLY
), 전체 또는 할당 개별 요소로 배열을 설정합니다.
노력할만한 가치가 없을 것입니다. perl
Bourne / POSIX 셸 배열을 사용 하거나 제한합니다 "$@"
.
내부적으로 배열을 사용하는 함수를 정의하기 위해 사용자의 대화식 쉘에서 일부 파일을 소싱하려는 의도가 있다면 유용한 몇 가지 참고 사항이 있습니다.
로컬 범위 (함수 또는 익명 함수)의 배열 zsh
과 유사하게 배열을 구성 할 수 있습니다 ksh
.
myfunction() {
[ -z "$ZSH_VERSION" ] || setopt localoption ksharrays
# use arrays of indice 0 in this function
}
또한 다음을 사용하여 에뮬레이션 할 수 있습니다 ksh
( ksh
배열 및 기타 여러 영역과의 호환성 향상 ).
myfunction() {
[ -z "$ZSH_VERSION" ] || emulate -L ksh
# ksh code more likely to work here
}
이를 염두에두고 파생 버전의 이전 버전과 이전 버전에 대한 지원을 기꺼이 포기 yash
하고 희소 배열을 만들지 않는 한 일관성있게 사용할 수 있어야합니다.ksh88
pdksh
a[0]=foo
a=(foo bar)
(하지만 아닙니다 a=()
)
"${a[#]}"
, "${a[@]}"
,"${a[0]}"
이 이러한 기능에 emulate -L ksh
그동안, zsh
사용자가 정상적으로 그 / 그녀의 배열 zsh을 방법을 사용하여.