Adgang til variabel med variabelindeks fra bash shell script loop?

Jeg ønsker at få adgang til array-indeksvariablen, mens jeg går gennem en array i mit bash shell-script.

myscript.sh

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

Resultatet af ovenstående script er:

foo bar baz bat 

Det resultat, jeg søger, er:

0 1 2 3 

Hvordan ændrer jeg mit script for at opnå dette?

Kommentarer

  • Bemærk også, at du stort set aldrig vil have "${array[*]}" i stedet for "${array[@]}". Brug af * i stedet for @ behandler det mere eller mindre som en streng i stedet for en matrix.

Svar

Du kan gøre dette ved hjælp af Liste over array-nøgler . Fra bash mandesiden:

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

Liste over arraynøgler . Hvis navn er en matrixvariabel, udvides den til listen over matrixindekser (nøgler) tildelt i navnet. Hvis navnet ikke er et array, udvides det til 0, hvis navnet er angivet og ellers null. Når @ bruges, og udvidelsen vises inden for dobbelt anførselstegn, udvides hver tast til et separat ord.

For dit eksempel:

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

Dette resulterer i:

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

Bemærk at dette også arbejde for ikke-successive indekser:

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

Dette resulterer i:

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

Kommentarer

  • Selvom dette svar opnår det ønskede resultat, tilsløres det unødigt af printf-sætningen. For eksempel: printf "$i=(${AR[i]})\n" eller echo "$i=(${ARi]})" giver begge lidt ekstra ved at vise, hvordan man får nøgle & var men strengt taget echo "$i" ville have svaret OP. Resten er " bash fu " 🙂
  • Hvorfor er det ikke muligt: a=(1 2);echo ${a[0]} # result: 1?

Svar

Ud over jordanms svar kan du også lave et C ligesom sløjfe i bash:

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

Kommentarer

  • Kun hvis det ikke var et sparsomt array …

Svar

du kan gøre noget som dette:

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

  • Hvad siger dette at pfnuesels svar siger ikke allerede?
  • Jeg kan tage fejl, men svarer pfnuesels ikke ikke matrixlængden på hver iteration igen?

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *