Stampa elementi dell'array su righe separate in Bash?


229

Come posso stampare l'elemento array di un array Bash su righe separate? Questo funziona, ma sicuramente c'è un modo migliore:

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

Ho provato questo ma non ha funzionato:

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

Risposte:


436

Prova a fare questo:

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

La differenza tra $@e $*:

  • Non quotato, i risultati non sono specificati. In Bash, entrambi si espandono per separare gli arg e quindi si spaccano e si lasciano andare.

  • Citato, "$@"espande ogni elemento come argomento separato, mentre si "$*" espande in args unito in un argomento: "$1c$2c..."(dove cè il primo carattere di IFS).

Quasi sempre lo vuoi "$@". Lo stesso vale per "${arr[@]}".

Citali sempre!


5
E nota, le doppie virgolette attorno al riferimento della variabile sono importanti se vuoi assicurarti che gli elementi con spazi interni non vengano inavvertitamente divisi.
danfuzz,

4
@sputnick: non funziona, gli elementi dell'array finiscono su un'unica riga
Axel Bregnsbo,

1
A cosa servono i due trattini dopo il comando? Non ho trovato riferimenti ad esso nel manuale.
joanpau,

3
C'è un modo per farlo in modo che non produca righe vuote se non ci sono elementi nell'array senza doverlo fare | grep -v '^$'?
Noel Yap,

2
@espaciomore '% s \ n' è il formato per l'output della funzione printf. % s indica un segnaposto per un argomento stringa (in questo caso l'elemento array) e \ n aggiunge un'interruzione di riga dopo. Pertanto, ci sarà una stringa e un'interruzione di linea nell'output per ciascun elemento dell'array.
Koja

71

Basta citare l'argomento per fare eco:

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

la sub shell aiuta a ripristinare l'IFS dopo l'uso


3
scusate perreal, ho spostato il mio segno di spunta su sputnick, nonostante mi piaccia di più la vostra soluzione, solo perché ho imparato a conoscere la funzione 'printf'.
Axel Bregnsbo,

3
Grazie per questa risposta - mi piace! Dopo l'espansione si verificano compiti errati, quindi IFS=$'\n' echo "${my_array[*]}"non funziona. Oh bene!
Cxw

@cxw, cosa intendi con "incarichi accaduti"?
Steven Shaw,

1
@bschlueter, ho provato con Bash 4 - 4.4.23 (1) -release - e funziona!
Steven Shaw,

1
@cxw Ah, non ho visto cosa stavi cercando di fare lì. Penso che non funzioni perché echoè incorporato in Bash. Tuttavia, puoi avvolgerlo in una funzione e funzionerà! gist.github.com/steshaw/53ba0095bce8ccab52d26a14375dedb8
Steven Shaw

40

Utilizzando per :

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

Utilizzando la cronologia ; nota che questo fallirà se i tuoi valori contengono !:

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

Utilizzando basename ; nota che questo fallirà se i tuoi valori contengono /:

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

Usando shuf ; si noti che i risultati potrebbero non essere pubblicati in ordine:

shuf -e "${alpha[@]}"

19
"shuf" ... "potrebbe non venire in ordine" ... divertente.
Walf,

4
per shuf. Chi avrebbe mai pensato di usarlo?
fbicknel,

3

Ho provato le risposte qui in un gigante per ... if loop, ma non ho avuto alcuna gioia - quindi l'ho fatto in questo modo, forse disordinato ma ha fatto il lavoro:

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

anche se questo ha aggiunto uno spazio all'elenco, il che va bene - volevo che fosse rientrato un po '. Supponiamo anche che "\ n" possa essere stampato nell'originale $ EP_LIST.


5
Non sembra un esempio completo.
Kenorb,

3

Un'altra variante utile è pipe per tr:

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

Sembra semplice e compatto


11
Tranne questo si interrompemy_array=( "one two" three )
Mike Holt,

Risolto il problema con virgolette doppie.
Steven Shaw,

Non ha funzionato come pubblicizzato su Bash versione 4+, echo "${my_array[@]}" | tr '' ' \n'ho dovuto usare , anche se personalmente eviterei di usarlo echocosì, dove la trmia scelta penso che qualcosa del genere tr '' ' \n' <<<"${my_array[@]}"potrebbe essere un po 'più facile da leggere in seguito.
S0AndS0
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.