Array-Elemente in Bash? In separaten Zeilen drucken?

228

Wie drucke ich das Array-Element eines Bash-Arrays in separaten Zeilen? Dieser funktioniert, aber es gibt sicherlich einen besseren Weg:

$ my_array=(one two three)
$ for i in ${my_array[@]}; do echo $i; done
one
two
three

Versuchte dies, aber es hat nicht funktioniert:

$ IFS=$'\n' echo ${my_array[*]}
one two three
Axel Bregnsbo
quelle

Antworten:

435

Versuchen Sie Folgendes:

$ printf '%s\n' "${my_array[@]}"

Der Unterschied zwischen $@und $*:

  • Nicht zitiert, sind die Ergebnisse nicht spezifiziert. In Bash werden beide erweitert, um Argumente zu trennen, und dann werden Wörter geteilt und globalisiert.

  • In Anführungszeichen wird "$@"jedes Element als separates Argument "$*" erweitert , während es zu den Argumenten erweitert wird, die zu einem Argument zusammengeführt wurden: "$1c$2c..."(wobei cdas erste Zeichen von IFS).

Du willst fast immer "$@". Gleiches gilt für "${arr[@]}".

Zitiere sie immer!

Gilles Quenot
quelle
5
Beachten Sie, dass die doppelten Anführungszeichen um die Variablenreferenz wichtig sind, wenn Sie sicherstellen möchten, dass Elemente mit internen Leerzeichen nicht versehentlich aufgeteilt werden.
Danfuzz
4
@ Sputnick: funktioniert nicht, die Array-Elemente landen in einer einzigen Zeile
Axel Bregnsbo
1
Wofür sind die beiden Bindestriche nach dem Befehl? Ich habe im Handbuch keine Hinweise darauf gefunden.
Joanpau
3
Gibt es eine Möglichkeit, es so zu gestalten, dass keine Leerzeilen ausgegeben werden, wenn das Array keine Elemente enthält, ohne dass dies erforderlich ist | grep -v '^$'?
Noel Yap
2
@espaciomore '% s \ n' ist das Format für die Ausgabe der printf-Funktion. % s bedeutet einen Platzhalter für ein Zeichenfolgenargument (in diesem Fall das Array-Element) und \ n fügt danach einen Zeilenumbruch hinzu. Daher gibt es für jedes Element im Array eine Zeichenfolge und einen Zeilenumbruch in der Ausgabe.
Koja
71

Zitieren Sie einfach das Argument, um zu wiederholen:

( IFS=$'\n'; echo "${my_array[*]}" )

Die Sub-Shell hilft bei der Wiederherstellung des IFS nach der Verwendung

perreal
quelle
3
sorry perreal, ich habe mein Häkchen auf sputnick verschoben, obwohl mir deine Lösung besser gefallen hat, nur weil ich etwas über die Funktion 'printf' gelernt habe.
Axel Bregnsbo
3
Danke für diese Antwort - ich mag es! Schade, dass Zuweisungen nach der Erweiterung auftreten und daher IFS=$'\n' echo "${my_array[*]}"nicht funktionieren. Naja!
cxw
@cxw, was meinst du mit "Aufgaben passieren"?
Steven Shaw
1
@bschlueter, ich habe es mit Bash 4 versucht - 4.4.23 (1) -release - und es funktioniert!
Steven Shaw
1
@cxw Ah, ich habe nicht gesehen, was du dort versucht hast. Ich denke, es funktioniert nicht, weil echoes in Bash eingebaut ist. Sie können es jedoch in eine Funktion einbinden und es wird funktionieren! gist.github.com/steshaw/53ba0095bce8ccab52d26a14375dedb8
Steven Shaw
40

Verwenden für :

for each in "${alpha[@]}"
do
  echo "$each"
done

Verwenden der Geschichte ; Beachten Sie, dass dies fehlschlägt, wenn Ihre Werte Folgendes enthalten !:

history -p "${alpha[@]}"

Verwenden des Basisnamens ; Beachten Sie, dass dies fehlschlägt, wenn Ihre Werte Folgendes enthalten /:

basename -a "${alpha[@]}"

Mit shuf ; Beachten Sie, dass die Ergebnisse möglicherweise nicht in der richtigen Reihenfolge angezeigt werden:

shuf -e "${alpha[@]}"
Steven Penny
quelle
19
"shuf" ... "könnte nicht in der richtigen Reihenfolge herauskommen" ... urkomisch.
Walf
4
für shuf. Wer hätte gedacht, das zu nutzen?
Fbicknel
3

Ich habe die Antworten hier in einem Riesen für ... if-Schleife ausprobiert, aber keine Freude bekommen - also habe ich es so gemacht, vielleicht chaotisch, aber den Job gemacht:

 # EXP_LIST2 is iterated    
 # imagine a for loop
     EXP_LIST="List item"    
     EXP_LIST2="$EXP_LIST2 \n $EXP_LIST"
 done 
 echo -e $EXP_LIST2

obwohl das der Liste ein Leerzeichen hinzufügte, was in Ordnung ist - ich wollte, dass es ein bisschen eingerückt wird. Angenommen, das "\ n" könnte in der ursprünglichen $ EP_LIST gedruckt werden.

wuxmedia
quelle
5
Sieht nicht nach einem vollständigen Beispiel aus.
Kenorb
3

Eine weitere nützliche Variante ist Pipe to tr:

echo "${my_array[@]}" | tr ' ' '\n'

Das sieht einfach und kompakt aus

0x00
quelle
11
Außer das bricht ammy_array=( "one two" three )
Mike Holt
Es wurde mit doppelten Anführungszeichen behoben.
Steven Shaw
Funktionierte nicht wie in Bash Version 4+ angekündigt , musste verwendet werden echo "${my_array[@]}" | tr '' ' \n', obwohl ich persönlich vermeiden würde, so etwas zu verwenden echo, wo trmeine Wahl meiner Meinung tr '' ' \n' <<<"${my_array[@]}"nach später etwas einfacher zu lesen sein könnte.
S0AndS0