Åtkomst till arrayindexvariabel från bash shell-skriptslinga?

Jag vill komma åt arrayindexvariabeln medan jag går igenom en array i mitt bash shell-skript.

myscript.sh

#!/bin/bash AR=("foo" "bar" "baz" "bat") for i in ${AR[*]}; do echo $i done 

Resultatet av ovanstående skript är:

foo bar baz bat 

Resultatet jag söker är:

0 1 2 3 

Hur ändrar jag mitt skript för att uppnå detta?

Kommentarer

  • Observera också att du i princip aldrig vill ha "${array[*]}" istället för "${array[@]}". Att använda * istället för @ behandlar det mer eller mindre som en sträng istället för en array.

Svar

Du kan göra detta med Lista över arraynycklar . Från bash mansidan:

${!name[@]}
${!name[*]}

Lista över arraynycklar . Om namnet är en matrisvariabel expanderar den till listan över matrisindex (nycklar) som tilldelats i namn. Om namnet inte är en matris, expanderar det till 0 om namnet är inställt och annars är null. När @ används och expansionen visas inom dubbla citat, expanderar varje nyckel till ett separat ord.

För ditt exempel:

#!/bin/bash AR=("foo" "bar" "baz" "bat") for i in "${!AR[@]}"; do printf "${AR[%s]}=%s\n" "$i" "${AR[i]}" done 

Detta resulterar i:

${AR[0]}=foo ${AR[1]}=bar ${AR[2]}=baz ${AR[3]}=bat 

Observera att detta också arbeta för icke-successiva index:

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

Detta resulterar i:

${AR[3]}=foo ${AR[5]}=bar ${AR[7]}=bat ${AR[25]}=baz 

Kommentarer

  • Även om det här svaret uppnår det önskade resultatet försvinner det i onödan av printf-uttalandet. Till exempel: printf "$i=(${AR[i]})\n" eller echo "$i=(${ARi]})" båda ger lite extra genom att visa hur man får nyckel & var men strikt taget echo "$i" skulle ha svarat på OP. Resten är " bash fu " 🙂
  • Varför är det inte möjligt: a=(1 2);echo ${a[0]} # result: 1?

Svar

Förutom jordanms svar kan du också göra ett C som slinga i bash:

for ((idx=0; idx<${#array[@]}; ++idx)); do echo "$idx" "${array[idx]}" done 

Kommentarer

  • Endast om det inte var en gles array …

Svar

du kan göra något liknande detta:

 #!/bin/bash AR=("foo" "bar" "baz" "bat") length=${#AR[@]} for (( i = 0; i < length; i++ )); do echo "$i" done  

output:

0 1 2 3 

Kommentarer

  • Vad säger detta att pfnuesels svar säger inte redan?
  • Jag kan ha fel men svarar pfnuesels svar inte om matrislängden på varje iteration på nytt?

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *