bash로 배열의 마지막 요소를 읽는 방법이 있습니까?


68

예를 들어 5 개의 요소가있는 배열이있는 경우 :

[a][b][c][d][e]

echo ${myarray[4]}내가 사용하는 것을 볼 수 있습니다.

그러나 주어진 배열의 요소 수를 모른다면 어떻게해야합니까? 알 수없는 길이 배열의 마지막 요소를 읽는 방법이 있습니까? 즉, 배열의 오른쪽에서 왼쪽으로 읽는 첫 번째 요소는 무엇입니까?

bash에서 이것을 수행하는 방법을 알고 싶습니다.


$@정확히 배열이 아닙니다 (아래 첨자 사용 불가). 이에 대해서는 쉘 스크립트에 전달 된 마지막 인수 얻기를 참조하십시오 .
Tom Hale

답변:


89

음수 색인 ${myarray[-1]}사용 하여 마지막 요소를 얻을 수 있습니다 . 두 번째 마지막에 대해서도 같은 작업을 수행 할 수 있습니다. 배쉬에서 :

인덱스 배열의 요소를 참조하는 데 사용 된 아래 첨자가 0보다 작은 숫자로 평가되면 배열의 최대 인덱스보다 큰 것으로 해석되므로 배열의 끝에서 음의 인덱스가 다시 계산됩니다. 인덱스 -1은 마지막 요소를 나타냅니다.

할당에도 동일하게 적용됩니다. "표현"이라고 할 때 실제로는 표현을 의미합니다. 배열의 길이를 ${#myarray[@]}명시 적으로 사용하여 계산하는 것을 포함하여 인덱스를 계산하기 위해 모든 산술 표현식을 작성할 수 있습니다 .


2
당신은에 그렇게 할 수 kshzsh뿐만 아니라.
Janis

5
zsh하지만, 기본 배열은에 의해 1 인덱스 달리 bash하고 ksh그들이 어디에 0 인덱스.
Stephen Kitt

2
물론입니다. 이 질문에 대한 짧은 대답은 변하지 않지만, 긴 형식이 언급 된 이후 행동의 차이를 지적 할 필요가 있다고 생각했습니다.
Stephen Kitt

22
음수 인덱스는 bash 4.3 이상에서만 작동합니다.
cuonglm

10
v10.11.5 이상으로 Mac OS X에 포함 된 Bash 버전은 3.2에 불과하므로 Mac에서는 작동하지 않습니다.
Doktor J

44

최신 배쉬 (v4.1 이상)

index에서 마지막 요소를 읽을 수 있습니다 -1.

$ a=(a b c d e f)
$ echo ${a[-1]}
f

bash 버전 4.1-alpha로 시작 하는 음의 인덱스를 사용하여 끝에서 숫자 인덱스 배열에 액세스하는 지원 .

이전 배쉬 (v4.0 이하)

${#a[@]}마지막 요소를 얻으려면 배열 길이 를 가져 와서 빼야합니다.

$ echo ${a[${#a[@]}-1]}
f

bash는 배열 첨자를 산술 표현식으로 취급하므로 $((...))산술 평가를 강제하기 위해 와 같은 추가 표기법이 필요하지 않습니다 .


마지막 것은 나를 위해 작동하지 않습니다; Bash v4.1.2 (1)를 사용하고 있습니다. 마지막 항목을 인쇄하는 대신 전체 배열을 인쇄합니다.
Alexej Magura

그러나 @cuonglm의 답변은 효과가 있습니다.
Alexej Magura

modern버전으로 자격 을 갖추면 더 나은 답변을 얻을 수 있습니다 .
Samveen

1
정답자를 완벽하게 만드는 데 필요한 것.
Samveen

1
감사합니다. "bash가 배열 첨자를 산술 식으로 취급한다"는 것에 대해 몰랐기 때문에 echo $ {a [$ (($ {# a [@]}-1]))}을 사용하고있었습니다.
Bruno Bronosky

15

bash음수 인덱스로 배열 할당, 참조, 설정 해제 는 bash 4.3 에서만 추가되었습니다 . 의 이전 버전 bash에서는 index 식을 사용할 수 있습니다array[${#array[@]-1}]

또 다른 방법은 이전 버전 bash(bash 3.0 이상) 에서도 작동합니다 .

$ a=([a] [b] [c] [d] [e])
$ printf %s\\n "${a[@]:(-1)}"
[e]

또는:

$ printf %s\\n "${a[@]: -1}"
[e]

오프셋 부정 사용하면 분리 할 필요 :-과 혼동을 피하기 위해 :-확장.


1
그것을 확인 "${a[@]: -1}"하고 그것은 (이외의 작동 bashzsh도) ksh.
Janis

Kornshell 문서 ( www2.research.att.com/sw/download/man/man1/ksh.html )는이를 완전히 지정합니다. ( zsh또는 의 문서를 검사 bash하지는 않았지만 세 가지 껍질 모두에서 테스트했습니다.)
Janis

@ Janis : bash 문서를 다시 읽으십시오. 또한 이것에 대해서도 언급했습니다. 다시 감사합니다.
cuonglm

4

정렬

bash (bash 3.0 이상부터)에서 가장 오래된 대안은 다음과 같습니다.

$ a=(aa bb cc dd ee)
$ echo "${a[@]:(-1)}   ${a[@]: -1}   ${a[@]:(~0)}   ${a[@]:~0}"
ee   ee   ee   ee

(기본값 사용) 의 확장으로 :마이너스 가 해석되는 것을 피하기 위해 공간이 필요합니다 .-"${var:-abc}"

~연산 인 비트 부정 (1의 보수와 동등 또는 모든 비트를 반전 ). 남자 배쉬에서 :

산술 평가

      ! ~         logical and bitwise negation  

bash-4.2 이상부터 :

$ echo "${a[-1]}   ${a[(~0)]}"
ee   ee

bash 5.0 이상부터 :

$ echo "${a[~0]}"
ee

모든 배쉬 버전 (이전 배쉬) :

$ echo "${a[   ${#a[@]}-1   ]}"    # spaces added **only** for readability
ee

@

위치 인수의 경우 (bash 2.01부터) :

$ set aa bb cc dd ee
$ echo "${@:(-1)} ${@:~0} ${@: -1} ${@:$#}   ${!#}"
ee ee ee   ee

모든 쉘을위한 휴대용 솔루션은 eval을 사용하는 것입니다.

eval printf '"%s\n"' \"\${$#}\"

bash 5+ 구문에 대한 참조가 있습니까? 매뉴얼~ 에서 58 개의 인스턴스를 모두 검색 했지만 보지 못했습니다.
Tom Hale

... 어떻게하면 $@되나요? bash: ${@[@]:(-1)}: bad substitution
Tom Hale

1
예, man bash참조가 있습니다 (@ 제목에서 확장 된 답변 확인). @TomHale
이삭

1
@것입니다 하지 배열 (물론,하지 완벽하게 배열 bash는) 그것은 인덱스 (동의하지 않는 []개별 인수에 대한) 첨자. 사용해야 ${@:(-1)}합니다. @제목 에서 확장 된 항목을 확인하십시오 . @TomHale
이삭

-2

또한 당신은 이것을 할 수 있습니다 :

$ a=(a b c d e f)
$ echo ${a[$(expr ${#a[@]} - 1)]}

결과:

$ f

당신이하고있는 일은 배열의 모든 요소 수를 얻고 0 인 배열 색인에서 시작하지 않고 모든 요소를 ​​얻으므로 -1을 빼는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.