Jak mogę odczytać dane wejściowe użytkownika jako tablicę w Bash?

15

Jak mogę odczytać dane wejściowe użytkownika jako tablicę w bashpowłoce?

moata_u
źródło
Zakładam, że chcesz czytać ze standardu? Moja odpowiedź będzie również działać z wykonaniem typu cat war_and_peace.txt | ./array_test.sh.
Stefano Palazzo
Lub po prostu ./array_test.sh < war_and_peace.txt.
Eliah Kagan

Odpowiedzi:

14

Oto jeden ze sposobów, aby to zrobić:

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

echo ${my_array[@]}

Jeśli go po prostu uruchomisz, będzie kontynuował czytanie ze standardowego wejścia, dopóki nie naciśniesz Ctrl + D (EOF). Następnie wprowadzone linie będą w my_array. Niektórzy mogą uznać ten kod za mylący. Ciało pętli w zasadzie mówi my_array = my_array + element.

Kilka interesujących dokumentów:

Stefano Palazzo
źródło
3
read -rjest czasem bardzo przydatny / ważny ... Link Stefano do „przeczytanej wbudowanej strony man” wyjaśnia jej cel ... (zapobieganie interpretacji odwrotnego ukośnika).
Peter.O,
10

Przeczytaj to za pomocą tego:

read -a arr

Do drukowania użyj:

for elem in ${arr[@]}
do 
  echo $elem
done
ABcDexter
źródło
4

I taki, który nie odtwarza tablicy za każdym razem (choć wymaga bash 3.1 lub nowszej wersji):

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[@]}"

Więcej informacji można znaleźć na stronie http://mywiki.wooledge.org/BashFAQ/001 .

I jak zawsze, aby uniknąć pisania błędów, przeczytaj http://mywiki.wooledge.org/BashGuide i unikaj przewodników tldp, takich jak Przewodnik zaawansowanego skryptu bash.

geirha
źródło
Ładne linki ... Dziękujemy za zwrócenie uwagi na IFSproblem. Bez zerowania, „czytaj” kopiuje wszystkie wiodące i końcowe białe znaki ... i oczywiście -rteż ...
Peter.O
0

Co powiesz na ten jednowarstwowy;)

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

Edytować:

w bash,

arr=(val1 val2 ...)

to sposób przypisywania do tablicy . Używając go w połączeniu z zastępowaniem poleceń, możesz czytać tablice z potoku, których nie można użyć readdo osiągnięcia tego w prosty sposób:

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

Przekonasz się, że nie wyprowadza nic ze względu na fakt, że readnic nie robi, gdy stdinjest potokiem, ponieważ potok może być uruchamiany w podpowłoce, dzięki czemu zmienna może w ogóle nie być użyteczna.

Korzystając ze sposobu sugerowanego przez tę odpowiedź:

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

Daje a bto, co jest o wiele prostsze i bardziej bezpośrednie niż jakiekolwiek obejście podane przez odpowiedzi Read wartości do zmiennej powłoki z potoku i w skrócie odczytane po tym, jak potok nie ustawia wartości .

twaróg
źródło
przetestowałeś to?
cmak.fr
@ cmak.fr tak, to działa dla mnie
Quark
@ Melebius Dołączyłem wyjaśnienie tego i zaletę tego jednowierszowego.
JiaHao Xu