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
0
als 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.