Come posso leggere l'input dell'utente come un array in Bash?


15

Come potrei leggere l'input dell'utente come array nella bashshell?


Presumo che tu voglia leggere da Stdin? La mia risposta funzionerà anche con l'esecuzione come cat war_and_peace.txt | ./array_test.sh.
Stefano Palazzo

O semplicemente ./array_test.sh < war_and_peace.txt.
Eliah Kagan,

Risposte:


14

Ecco un modo per farlo:

while read line
do
    my_array=("${my_array[@]}" $line)
done

echo ${my_array[@]}

Se lo esegui, continuerà a leggere dallo standard input fino a quando premi Ctrl + D (EOF). Successivamente, le linee inserite saranno presenti my_array. Alcuni potrebbero trovare questo codice confuso. Fondamentalmente dice il corpo del ciclo my_array = my_array + element.

Alcuni interessanti documenti:


3
read -rè abbastanza utile / importante a volte ... Il link di Stefano alla "manpage builtin man" spiega il suo scopo ... (per impedire l'interpretazione della barra rovesciata).
Peter

10

Leggilo usando questo:

read -a arr

E per la stampa, utilizzare:

for elem in ${arr[@]}
do 
  echo $elem
done

4

E uno che non ricrea l'array ogni volta (anche se richiede bash 3.1 o versioni successive):

array=()
while IFS= read -r -p "Next item (end with an empty line): " line; do
    [[ $line ]] || break  # break if line is empty
    array+=("$line")
done

printf '%s\n' "Items read:"
printf '  «%s»\n' "${array[@]}"

Vedi http://mywiki.wooledge.org/BashFAQ/001 per ulteriori informazioni.

E come sempre, per evitare di scrivere bug leggi http://mywiki.wooledge.org/BashGuide ed evita le guide tldp come la guida avanzata di scripting bash.


Bei link ... Grazie per aver segnalato il IFSproblema. Senza annullarlo, "leggi" tutti gli spazi iniziali e finali ... e ovviamente -ranche ...
Peter.O

0

Che ne dici di questo one-liner;)

arr=( $(cat -) )
echo ${arr[@]}

Modificare:

In bash,

arr=(val1 val2 ...)

è il modo di assegnare a un array . Usandolo insieme alla sostituzione dei comandi, è possibile leggere in array dalla pipeline che non è possibile utilizzare readper ottenere ciò in modo semplice:

echo -e "a\nb" | read -a arr
echo ${arr[@]}

Scoprirai che non ha prodotto nulla a causa del fatto che readnon fa nulla quando stdinè una pipa poiché una pipeline può essere eseguita in una subshell in modo che la variabile possa non essere affatto utilizzabile.

Utilizzando il modo suggerito da questa risposta:

arr=(`echo -e "a\nb"`)
echo ${arr[@]}

a bqual è il modo più semplice e più diretto di qualsiasi soluzione alternativa data dalle risposte dei valori di lettura in una variabile shell da una pipe e in bash letti dopo che una pipe non sta impostando valori .


l'hai provato?
cmak.fr

@ cmak.fr sì, funziona per me
Quark

@Melebius Ne ho aggiunto una spiegazione e il vantaggio di questo one-liner.
JiaHao Xu,
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.