Ich möchte eine Datei zeilenweise in ein Skript einlesen. Jede Zeile in der Datei besteht aus mehreren Werten, die durch einen Tabulator getrennt sind. Ich möchte jede Zeile in ein Array einlesen.
Ein typisches Bash-Beispiel "Datei nach Zeile lesen";
while read line
do
echo $line;
done < "myfile"
Für mich sieht myfile jedoch so aus (tabulatorgetrennte Werte);
value1 value2 value3
value4 value5 value6
Bei jeder Wiederholung der Schleife möchte ich, dass jede Zeile in ein Array geht, so dass ich es kann
while read line into myArray
do
echo myArray[0]
echo myArray[1]
echo myArray[2]
done < "myfile"
Dies würde das Folgende in der ersten Schleifeniteration ausgeben;
value1
value2
value3
Bei der zweiten Iteration würde es dann gedruckt werden
value4
value5
value6
Ist das möglich? Die einzige Möglichkeit, die ich sehen kann, ist, eine kleine Funktion zu schreiben, um die Werte manuell herauszuziehen. Gibt es dafür eine Unterstützung in bash?
Du bist ganz in der Nähe:
while IFS=$'\t' read -r -a myArray
do
echo "${myArray[0]}"
echo "${myArray[1]}"
echo "${myArray[2]}"
done < myfile
(Der -r
teilt der read
mit, dass \
in den Eingabedaten nicht speziell ist; der -a myArray
fordert ihn auf, die Eingabezeile in Wörter aufzuteilen und die Ergebnisse in myArray
zu speichern, und der IFS=$'\t'
sagt dazu, dass anstelle von nur Wörter verwendet werden Der reguläre Standard von Bash erlaubt auch Leerzeichen, um Wörter zu trennen. Beachten Sie, dass dieser Ansatz einen oder mehrere Tabs als Trennzeichen behandelt. Wenn also ein Feld leer ist, werden spätere Felder in frühere Positionen in verschoben das Array. Ist das in Ordnung?)
Wenn Sie wirklich jedes Wort (Bash-Bedeutung) in einen anderen Array-Index aufteilen möchten, der das Array bei jeder Durchlaufschleife durchläuft, ist die Antwort von @ ruakh der richtige Ansatz. Sie können jedoch die read-Eigenschaft verwenden, um jedes gelesene Word in verschiedene Variablen column1
, column2
, column3
zu zerlegen, wie in diesem Code-Snippet
while IFS=$'\t' read -r column1 column2 column3 ; do
printf "%b\n" "column1<${column1}>"
printf "%b\n" "column2<${column2}>"
printf "%b\n" "column3<${column3}>"
done < "myfile"
um ein ähnliches Ergebnis zu erzielen, vermeiden Sie den Zugriff auf den Array-Index und verbessern die Lesbarkeit des Codes, indem Sie sinnvolle Variablennamen verwenden (natürlich ist columnN
keine gute Idee).
Sie könnten auch versuchen,
OIFS=$IFS;
IFS="\t";
animals=`cat animals.txt`
animalArray=$animals;
for animal in $animalArray
do
echo $animal
done
IFS=$OIFS;