Stdin in ein Bash-Array einlesen


7

Ich möchte das Äquivalent von erreichen:

list=()
while read i; do
  list+=("$i")
done <<<"$input"

mit

IFS=$'\n' read -r -a list <<<"$input"

Was mache ich falsch?

input=`/bin/ls /`

IFS=$'\n' read -r -a list <<<"$input"

for i in "${list[@]}"; do
  echo "$i"
done

Dies sollte eine Liste von drucken /, aber ich bekomme nur den ersten Artikel.


4
Wenn Sie wirklich versuchen, die Ausgabe von zu analysieren ls, tun Sie dies nicht. Verwenden Sie list=(/*).
Chepner

Antworten:


11

Sie müssen mapfile (oder das in eingeführte Synonym readarraybash 4.0 ) verwenden:

mapfile -t list <<<"$input"

Ein Leseaufruf nur Arbeit mit einer Zeile, nicht der gesamten Standardeingabe.

read -a listFüllen Sie den Inhalt der ersten Standardzeile in das Array ein list. In Ihrem Fall haben Sie binals einziges Element in der Array-Liste.


2
@cuonglm Das IFSist nutzlos, weil mapfilees bei seiner Eingabe keine Wortteilung macht.
Chepner

@ StéphaneChazelas: Mein schlechtes, entfernt es.
Cuonglm

5

Lösung für Bash Version 3 (und 4)

Ich war zufällig bei einer CentOS 5-Box mit Bash 3 angemeldet und hatte an einer Lösung gearbeitet. Ich habe die Antwort von cuonglm bereits positiv bewertet, aber ich dachte, ich könnte genauso gut die Lösung veröffentlichen, die ich gefunden habe und die mit Bash 3 (und 4) funktionieren sollte. Ich habe es mit einer Datei getestet, deren Name ein Leerzeichen enthält, und mit einer anderen, die mit beginnt -.

Anstatt

IFS=$'\n' read -r -a list <<<"$input"

Verwenden Sie einfach die Befehlssubstitution, um das Array zu erstellen und zu füllen:

IFS=$'\n' # split on newline only
set -f    # disable globbing
list=($(printf "%s" "$input"))

Hinweis: Dies funktioniert nicht mit Dateinamen, deren Name Zeilenumbrüche enthält.


4

für bashVersionen, die nicht unterstützenmapfile

IFS=$'\n' read -ra list -d '' <<< "$input"

sollte den Trick machen


2
Ein kleiner Nachteil; Dieser Befehl hat immer einen Exit-Status ungleich Null.
Chepner

2
Beachten Sie auch, dass leere Elemente entfernt werden.
Stéphane Chazelas
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.