Aufzählung aller anderen Array-Elemente in einer Schleife

Aufzählung aller anderen Array-Elemente in einer Schleife

Ich habe ein dynamisches Array mit Schlüsselpaarwerten und möchte diese auflistenjeder andereWert. In diesem Fall nur die Namen im Array. Da ich Bash v4 nicht verwende, konnte ich seqmit Echo durch ein Array blättern.

$ array=(Guido yes Francesca no Balthazar yes)
for x in $(seq 0 2 ${#array[@]});do echo $x;done
0
2
4
6

Dies gibt ein Element mehr zurück als die Paare, die ich habe (aufgrund des Offsets von 0), aber ich kann das mit einfacher Bash-Mathematik berücksichtigen:

for x in $(seq 0 2 $((${#array[@]}-1)));do echo $x;done
0
2
4

Das funktioniert einwandfrei. Aber sobald ich versuche, Elemente aus zu ziehen $array, erhalte ich einen Fehler, den ich nicht erklären kann. Ich habe es mit und ohne die „Mathematik“ versucht.

$ for x in $(seq 0 2 $((${#array[@]}-1)));do echo ${array[$x]};done
-bash: 0: syntax error: operand expected (error token is "0")

$ for x in $(seq 0 2 ${#array[@]});do echo ${array[$x]};done
-bash: 0: syntax error: operand expected (error token is "0")

Wie kann ich nur die Namen aus diesem dynamischen Array herausholen?

BEARBEITEN:mein $BASH_VERSIONist 3.2.57(1)-release(Mac OS X 10.10.2)

BEARBEITEN #2:Ich bin zu dem Schluss gekommen, dass dies möglicherweise ein Fehler in dieser Version ist. Da ich eine Reihe von AWS-Instanzen verwalte, habe ich beschlossen, sie zu überprüfen, und sie alle haben Bash 4.1.2(1). Ich habe meinen Mac auf diese Version aktualisiert und jetzt funktioniert es. Danke fürs Nachschauen, aber ich halte das für eine Anomalie.

Antwort1

Wenn Sie eine Schleife über abwechselnde Elemente des Arrays ausführen möchten, sollte dies unter Bash 3.2 funktionieren:

while IFS= read -d '' -r name; do
  # do something with "$name"
done < <(printf %s%.0s\\0 "${array[@]}")

Sie könnten ähnliche Dinge tun, xargs -0wenn das bequemer wäre.

Wenn beispielsweise keiner Ihrer Namen einen Doppelpunkt enthält, können Sie die Namen wie folgt in ein neues Array extrahieren:

IFS=: read -a names -r < <(printf %s%.0s: "${array[@]}")

(Leider können Sie den Feldtrenner nicht auf NUL setzen.)

All dies hängt davon ab, dass printfseine Formatzeichenfolge so oft wiederholt wird, wie es nötig ist, um alle seine Argumente zu verwenden (Posix-Verhalten, daher sollte es mit jeder Bash-Version oder mit dem nicht integrierten funktionieren printf). Das gelegentlich nützliche Format %.0sverwendet ein Argument und druckt höchstens 0 Zeichen davon, d. h. es legt es in den Bitbucket ab.

verwandte Informationen