wake-up-neo.net

Verwendung von 'readarray' in bash, um Zeilen aus einer Datei in ein 2D-Array zu lesen

Nehmen wir an, ich habe eine Textdatei 'demo.txt', die eine Tabelle wie diese enthält:

1 2 3    
4 5 6    
7 8 9    

Jetzt möchte ich jede Zeile separat mit dem Befehl 'readarray' in Bash lesen, also schreibe ich:

readarray myarray < demo.txt   

Das Problem ist, dass es nicht funktioniert. Wenn ich versuche, 'myarray' mit zu drucken:

echo $myarray

Ich bekomme:

1 2 3

Auch wenn ich schreibe:

echo ${myarray[1]}

Ich bekomme:

4 5 6

Anstatt:

2

wie ich erwartet habe. Warum das? Wie kann auf jede Zeile separat zugegriffen werden und in dieser Zeile Zugang zu jedem Mitglied erhalten? 

12
user3206874

Dies ist das erwartete Verhalten. readarray erstellt ein Array, in dem jedes Element des Arrays eine Zeile in der Eingabe ist. 

Wenn Sie das gesamte Array sehen möchten, müssen Sie es verwenden

echo "${myarray[@]}"

as echo "$myarray gibt nur myarray[0] aus und ${myarray[1]} ist die zweite Zeile der Daten.

Sie suchen ein zweidimensionales Array. Siehe zum Beispiel this .

Wenn Sie ein Array mit dem Inhalt der ersten Zeile wünschen, können Sie Folgendes tun:

$ read -a arr < demo.txt 
$ echo ${arr[0]}
1
$ echo ${arr[1]}
2
$ echo ${arr[2]}
3
12
damienfrancois
readarray rows < demo.txt                                           

for row in "${rows[@]}";do                                                      
  row_array=(${row})                                                            
  first=${row_array[0]}                                                         
  echo ${first}                                                                 
done 
4
Radu Gabriel

Wie kann auf jede Zeile separat zugegriffen werden und in dieser Zeile Zugang zu jedem Mitglied erhalten?

Im Bash-Referenzhandbuch bietet Bash eindimensionale indizierte und assoziative Array-Variablen. Sie erwarten also kannmatrix[1][2] oder ähnliches nicht. Sie können jedoch emulieren Matrix mit einem bash-Assoziationsarray zugreifen, wobei der Schlüssel eine multiple Dimension angibt.

Beispielsweise verwendet matrix[1,2] die Zeichenfolge "1,2" als assoziativen Feldschlüssel, der die 1. Zeile, 2. Spalte bezeichnet. Kombinieren Sie dies mit readarray:

typeset -A matrix
function load() {
    declare -a a=( $2 )
    for (( c=0; c < ${#a[@]}; c++ ))
    do
        matrix[$1,$c]=${a[$c]}
    done
}
readarray -C load -c 1 <<< $'1 2 3\n4 5 6\n7 8 9'
declare -p matrix
2
bishop

Um auf Damiens Antwort einzugehen (und da ich noch keine Kommentare einreichen kann ...), werden Sie nur durchgelesen. Was ich meine ist so etwas wie das Folgende

exec 5<demo.txt
for i in `seq 1 ${numOfLinesInFile}`
do
read -a arr -u 5
  for j in `seq 0 ${numOfColumnsMinus1}`
  do
  echo ${arr[$j]}
  done
done

Ich hoffe, du hast schon eine Lösung gefunden (sorry, bump ...). Ich stolperte über diese Seite, während ich half, einen Freund zu unterrichten, und dachte mir, dass andere das Gleiche tun könnten.

2
Eric

Tut mir leid, aber ich glaube, es gibt eine einfache und sehr saubere Lösung für Ihre Anfrage:

$ cat demo.txt
1 2 3
4 5 6
7 8 9
$ while read line;do IFS=' ' myarray+=(${line}); done < demo.txt
$ declare -p myarray
declare -a myarray='([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="7" [7]="8" [8]="9")'
$
1
Sebastien