2010-12-08 4 views
10

ich von http://bash.cyberciti.biz/guide/While_loop diesen Code habe, verwendet Zeile für ZeileBash, lesen Sie Zeile für Zeile aus der Datei, mit IFS

file=/etc/resolv.conf 
while IFS= read -r line 
do 
     # echo line is stored in $line 
    echo $line 
done < "$file" 

der Teil verstehe ich nicht aus einer Datei zu lesen ist IFS= und wie es trägt zu dieser Funktionalität bei. Kann mir das jemand erklären? Vielen Dank.

+0

Überprüfen Sie [die äquivalente Frage] (http://unix.stackexchange.com/q/209123/22565) unter [unix.SE]. –

Antwort

-5

IFS ist eine Variable für den Zeilentrenner (oder eigentlich "Interner Feldtrenner"). Dieser Code wird effektiv das Zeilentrennzeichen für Ihren Lesebefehl leeren und auf den Standardwert setzen. Manchmal wird IFS an anderer Stelle im Code geändert, weil Benutzer andere "Zeilen" -Endigungen wünschen, z. B. das Lesen eines Satzes (IFS=.) oder ähnliches.

Ich denke, sie haben die IFS= hier nur um sicherzustellen, dass es funktioniert oder jeder, unabhängig von dem vorherigen Wert auf der IFS-Variable. Der Code sollte immer noch ohne IFS=

+0

das ist wahr, ohne 'IFS =' es funktioniert immer noch gut. Danke vielmals. – wakandan

+0

nur eine schnelle Sache, können wir eine solche Zuordnung 'IFS =' und 'lesen -r Zeile 'in einer gleichen Zeile? Es ist erlaubt? – wakandan

+1

user121870, ja, es ist erlaubt. Wenn Variablen vor einen Befehl gestellt werden, ist die Variable nur für diesen Befehl sichtbar. Dies gilt für alle Bash-Befehle, auch wenn Sie selbst in Ihr Terminal schreiben. Probieren Sie zum Beispiel diesen Befehl: "MANWIDTH = 20 man bash". –

3

Im dritten Beispiel auf dieser Seite, Einstellung IFS auf Null verhindert Worttrennung, die diesen Code nicht funktioniert. Hier ist der Code:

while IFS= read -r field1 field2 field3 ... fieldN 
do 
    command1 on $field1 
    command2 on $field1 and $field3 
    .. 
    .... 
    commandN on $field1 ... $fieldN 
done < "/path/to dir/file name with space" 

Wie geschrieben, alle Worte auf der Linie gespeichert sind in field1 und field2, etc., sind leer. Ändern Sie die Zeile auf diese und es funktioniert einwandfrei:

while read -r field1 field2 field3 ... fieldN 
30

In diesem Fall wird IFS auf die leere Zeichenfolge gesetzt read von Strippen führende und nachfolgende Leerzeichen aus der Leitung zu verhindern.

Die Änderung IFS wird normalerweise durchgeführt, um zu steuern, wie die Eingabe in mehrere Felder aufgeteilt wird. Da in diesem Fall jedoch nur ein Variablenname an read übergeben wird, wird read die Eingabe niemals in mehrere Felder aufteilen, unabhängig vom Wert von IFS. Es wird jedoch die führenden und nachgestellten Whitespaces entfernen, wie in der POSIX-Spezifikation vorgeschrieben (vorausgesetzt, der Wert IFS enthält Leerzeichen oder ist nicht gesetzt).

Einzelheiten zur Funktionsweise finden Sie in der POSIX-Spezifikation für read und field splitting.

+5

+1 für die richtige Antwort geben. – grok12

-3

Um einen echten Linienseparator IFS zu machen, verwenden Sie IFS=$'\012'.

+1

Sie haben die Frage nicht beantwortet. Die Frage war, den Teil 'IFS =' im Befehl zu erklären und seine Verwendung zu erklären. Übrigens wäre 'IFS = $ '\ n'' (wohl) weniger kryptisch. –

+0

Ganz richtig. Aber dieser Teil wurde im Wesentlichen oben beantwortet, und dies sind die blutigen Details. Vielleicht sollten diese Fragen als beantwortet betrachtet werden. – user3673660

+0

Wenn die Frage bereits beantwortet wurde, ist es sinnlos, Antworten hinzuzufügen, die die Frage nicht beantworten. Na gut, es ist deine Entscheidung. vielleicht bekommst du sogar Upvotes dafür. Oder nicht. Warten wir es ab. –