Ik wil toegang krijgen tot de array-indexvariabele terwijl ik door een array loop in mijn bash-shellscript.
myscript.sh
#!/bin/bash AR=("foo" "bar" "baz" "bat") for i in ${AR[*]}; do echo $i done
Het resultaat van het bovenstaande script is:
foo bar baz bat
Het resultaat dat ik zoek is:
0 1 2 3
Hoe verander ik mijn script om dit te bereiken?
Reacties
Answer
U kunt dit doen met Lijst met arraysleutels . Van de bash man-pagina:
${!name[@]}
${!name[*]}Lijst met arraysleutels . Als naam een matrixvariabele is, wordt deze uitgebreid naar de lijst met matrixindices (sleutels) die in naam zijn toegewezen. Als naam geen array is, breidt uit naar
0als naam is ingesteld en anders null. Wanneer@wordt gebruikt en de uitbreiding tussen dubbele aanhalingstekens wordt weergegeven, wordt elke sleutel uitgebreid naar een afzonderlijk woord.
Voor uw voorbeeld:
#!/bin/bash AR=("foo" "bar" "baz" "bat") for i in "${!AR[@]}"; do printf "${AR[%s]}=%s\n" "$i" "${AR[i]}" done
Dit resulteert in:
${AR[0]}=foo ${AR[1]}=bar ${AR[2]}=baz ${AR[3]}=bat
Merk op dat dit ook werk voor niet-opeenvolgende indexen:
#!/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
Dit resulteert in:
${AR[3]}=foo ${AR[5]}=bar ${AR[7]}=bat ${AR[25]}=baz
Reacties
- Hoewel dit antwoord het gewenste resultaat oplevert, wordt het onnodig versluierd door de printf-instructie. Bijvoorbeeld:
printf "$i=(${AR[i]})\n"ofecho "$i=(${ARi]})"geven beide een beetje extra door te laten zien hoe je de sleutel & var maar strikt genomen zouecho "$i"het OP hebben beantwoord. De rest is " bash fu " 🙂 - Waarom is het niet mogelijk:
a=(1 2);echo ${a[0]} # result: 1?
Antwoord
Als aanvulling op het antwoord van Jordan kun je ook een C like loop in bash:
for ((idx=0; idx<${#array[@]}; ++idx)); do echo "$idx" "${array[idx]}" done
Reacties
- Alleen als het geen sparse array was …
Answer
je kunt zoiets als dit doen:
#!/bin/bash AR=("foo" "bar" "baz" "bat") length=${#AR[@]} for (( i = 0; i < length; i++ )); do echo "$i" done
output:
0 1 2 3
Reacties
- Wat zegt dit dat pfnuesels antwoord zegt het al niet?
- Ik vergis me misschien, maar evalueert het antwoord van pfnuesels de array-lengte niet opnieuw bij elke iteratie?
"${array[*]}"in plaats van"${array[@]}". Door*te gebruiken in plaats van@wordt het min of meer behandeld als een string in plaats van een array.