2017-06-26 2 views
0

Ich versuche, den Inhalt einer TXT-Datei in zwei Gruppen von Arrays in bash zu speichern. Die Datei ist eine Liste von Eigenschaften für bestimmte Datendateien, die durch vertikale Balken (|) voneinander getrennt sind. Bisher habe ich einen Code geschrieben, der die Datei liest und jede Datenzeile einzeln ausgibt, gefolgt von den jeweiligen Abschnitten der Zeile.Speichern von Daten in mehreren Arrays (Bash)

#prints line of text and then separated version 
while IFS='' read -r line || [[ -n "$line" ]] 
do 
    echo "Text read from file: $line" 
words=$(echo $line | tr "|" "\n") 
for tests in $words 
do 
    echo "> $tests" 
done 
done < "$1" 

Beispiel Ausgang:

Text read from file: this|is|data|in|a|file 
> this 
> is 
> data 
> in 
> a 
> file 
Text read from file: another|example|of|data 
> another 
> example 
> of 
> data 

Gibt es eine Möglichkeit für mich jede einzelne Zeile von Daten in einem Array zu speichern, und anschließend den zerkleinerten Teile davon in einem anderen? Ich dachte, dies wäre möglich mit einer Schleife, aber ich bin verwirrt von Arrays mit bash (newbie).

+1

Sie könnten darüber alles schief gehen - siehe [warum-ist-mit-a-Shell-Loop-to-Process-Text-betrachtet -bad-Praxis] (https://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice). –

Antwort

1

OK - Ich lese gerade die Zeilen wie Sie getan haben, und fügen Sie sie an die lines Array. Verwenden Sie dann tr, wie Sie getan haben, und hängen Sie an das Array words an. Verwenden Sie einfach die Klammern sie als Array-Elemente in den Zuordnungen zu markieren:

$ cat data.txt 
this|is|data|in|a|file 
another|example|of|data 

$ cat read_data.sh 
#!/bin/bash 
declare -a lines 
declare -a words 
while IFS='' read -r line || [[ -n "$line" ]] 
do 
    echo "Text read from file: $line" 
    lines+=($line) 
    words+=($(echo $line | tr "|" " ")) 
done < "$1" 

for ((ii=0; ii<${#lines[@]}; ii++)); do 
    echo "Line $ii ${lines[ii]}" 
done 

for ((ii=0; ii<${#words[@]}; ii++)); do 
    echo "Word $ii ${words[ii]}" 
done 

$ $ ./read_data.sh data.txt 
Text read from file: this|is|data|in|a|file 
Text read from file: another|example|of|data 
Line 0 this|is|data|in|a|file 
Line 1 another|example|of|data 
Word 0 this 
Word 1 is 
Word 2 data 
Word 3 in 
Word 4 a 
Word 5 file 
Word 6 another 
Word 7 example 
Word 8 of 
Word 9 data 
+0

Sie könnten auch Wörter mit bask Substitution tun: Wörter + = ($ {line // | /}) – grail

+0

Awesome! Vielen Dank. Ich habe einige Probleme mit meinen Daten, wenn zwischen zwei Merkmalen (innerhalb der gleichen Delimeter) ein Abstand besteht. Zum Beispiel: | 2017-06-20 11: 16: 39.103 | teilt sich in zwei "Word" - und "Line" -Indizes auf. Gibt es Tipps, wie Sie dies vermeiden können, anstatt den Abstand zwischen den beiden Merkmalen zu löschen? – WashU

+0

Ja. Da der Feldbegrenzer eine Pipe ist, vertausche Pipes mit Leerzeichen: 'words + = ($ (echo $ line | tr" | "" | "))' '. Nun, die Wörter, die Leerzeichen hatten, haben Pfeifen. Fügen Sie in der Schleife, die die Wörter anzeigt, diese Zeile hinzu, um die Pipes wieder in Leerzeichen zu ändern (pro Grals Vorschlag): 'words [ii] =" $ {words [ii] // | /} "' – Jack

Verwandte Themen