Chcę uzyskać dostęp do zmiennej indeksu tablicy podczas przeglądania tablicy w moim skrypcie powłoki bash.
myscript.sh
#!/bin/bash AR=("foo" "bar" "baz" "bat") for i in ${AR[*]}; do echo $i done
Wynik powyższego skryptu to:
foo bar baz bat
Wynik, którego szukam, to:
0 1 2 3
Jak zmienić skrypt, aby to osiągnąć?
Komentarze
Odpowiedź
Możesz to zrobić za pomocą listy kluczy tablic . Ze strony podręcznika bash
:
${!name[@]}
${!name[*]}
Lista kluczy tablicy . Jeśli nazwa jest zmienną tablicową, rozwija do listy indeksów tablic (kluczy) przypisanych w nazwie. Jeśli nazwa nie jest tablicą, jest interpretowana jako
0
, jeśli nazwa jest ustawiona, aw przeciwnym razie jest pusta. Kiedy@
jest używane, a rozwinięcie pojawia się w cudzysłowie, każdy klucz jest rozwijany do osobnego słowa.
Na przykład:
#!/bin/bash AR=("foo" "bar" "baz" "bat") for i in "${!AR[@]}"; do printf "${AR[%s]}=%s\n" "$i" "${AR[i]}" done
Daje to:
${AR[0]}=foo ${AR[1]}=bar ${AR[2]}=baz ${AR[3]}=bat
Zwróć uwagę, że praca dla kolejnych indeksów:
#!/bin/bash AR=([3]="foo" [5]="bar" [25]="baz" [7]="bat") for i in "${!AR[@]}"; do printf "${AR[%s]}=%s\n" "$i" "${AR[i]}" done
W rezultacie:
${AR[3]}=foo ${AR[5]}=bar ${AR[7]}=bat ${AR[25]}=baz
Komentarze
- Chociaż ta odpowiedź daje oczekiwany rezultat, jest niepotrzebnie zaciemniana przez instrukcję printf. Na przykład:
printf "$i=(${AR[i]})\n"
lubecho "$i=(${ARi]})"
dają trochę więcej, pokazując, jak uzyskać klucz & var, ale ściśle mówiącecho "$i"
, odpowiedziałoby na OP. Reszta to " bash fu " 🙂 - Dlaczego to niemożliwe:
a=(1 2);echo ${a[0]} # result: 1
?
Odpowiedź
Oprócz odpowiedzi jordanm możesz też zrobić C
like loop in bash
:
for ((idx=0; idx<${#array[@]}; ++idx)); do echo "$idx" "${array[idx]}" done
Komentarze
- Tylko jeśli nie była to rzadka tablica …
Odpowiedź
możesz zrobić coś takiego:
#!/bin/bash AR=("foo" "bar" "baz" "bat") length=${#AR[@]} for (( i = 0; i < length; i++ )); do echo "$i" done
wyjście:
0 1 2 3
Komentarze
- Co to oznacza, że odpowiedź pfnuesel jeszcze nie mówi?
- Mogę się mylić, ale czy odpowiedź pfnuesels nie ocenia ponownie długości tablicy przy każdej iteracji?
"${array[*]}"
zamiast"${array[@]}"
. Użycie*
zamiast@
traktuje mniej więcej jako ciąg znaków zamiast tablicy.