Ich habe diesen Thread gelesen: Wie werden die Zeilen einer Datei durchlaufen?
Was ist IFS
? Und wie wird es im Kontext von for
-loops verwendet?
Ich habe diesen Thread gelesen: Wie werden die Zeilen einer Datei durchlaufen?
Was ist IFS
? Und wie wird es im Kontext von for
-loops verwendet?
Antworten:
IFS
steht für - es ist ein Zeichen, das Felder trennt. In dem Beispiel, das Sie gepostet haben, ist es auf das Zeichen für eine neue Zeile ( ) gesetzt. Nachdem Sie dies eingestellt haben, wird der Text zeilenweise verarbeitet. In diesem Beispiel können Sie den Wert von (in einen Buchstaben, den Sie in Ihrer Eingabedatei haben) ändern und prüfen, wie der Text aufgeteilt wird.Input
Internal Field Separator
\n
for
IFS
Übrigens, von der Antwort, die Sie gepostet haben, ist die zweite Lösung die empfohlene ...
Wie @jasonwryan bemerkt hat, ist es nicht Input
aber Internal
. Name Input
kam von awk
dem es auch OFS
- gibt Output Field Separator
.
S
für separator in der Bourne-Shell war, woher es stammt. In der Korn-Shell und den meisten anderen Bourne-ähnlichen Shells, wie sie jetzt von spezifiziert wurden POSIX
, ist der S
is for Delimiter (erweitern Sie einfach Ihre Vorstellungskraft), da A::B:
er beispielsweise in "A", "" und "B" aufgeteilt ist (ohne Extrakosten) ""). Das unterscheidet sich von awk
's FS
oder der s
Parametererweiterung von zsh
.
IFS
ist nicht direkt mit dem Schleifen verbunden, sondern mit dem Teilen von Wörtern. IFS
Legt indirekt fest, wie die Ausgabe des Befehls in Teile aufgeteilt wird, über die die Schleife iteriert.
Wenn Sie eine ungeschützte Variablensubstitution $foo
oder Befehlssubstitution haben $(foo)
, gibt es zwei Fälle:
"$foo"
oder in einer variablen Zuweisung erfolgt x=$foo
, wird der aus der Ersetzung resultierende String unverändert verwendet.$IFS
wird, wird als Worttrennzeichen betrachtet. Zum Beispiel IFS=":"; foo="12:34::78"; echo $foo
Ausdrucke 12 34 78
(mit zwei Leerzeichen zwischen 34
und 78
, da es ein leeres Wort gibt).foo="*"; echo $foo
die Liste der Dateien im aktuellen Verzeichnis.Erwarten Sie für Schleifen wie für viele andere Kontexte eine Liste von Wörtern. So
for x in $(foo); do …
zerbricht $(foo)
in Wörter und behandelt jedes Wort als Glob-Muster. Der Standardwert von IFS
ist space, tab und newline . Wenn also foo
zwei Zeilen ausgedruckt werden hello world
und howdy
dann der Schleifenkörper mit x=hello
, dann x=world
und ausgeführt wird x=howdy
. Wenn IFS
explizit geändert wird, um nur eine neue Zeile zu enthalten, wird die Schleife für hello world
und ausgeführt howdy
. Wenn IFS
geändert zu werden o
, dann wird die Schleife für ausgeführt hell
, w
, rldh
(wobei 
ein Zeilenendezeichen) , und wdy
.
"IFS indirectly determines how ..."
?
IFS
(direkt) bestimmt, wie die Ausgabe der Befehlssubstitution aufgeteilt wird, die dann (indirekt) bestimmt, worüber die Schleife durchläuft.
Von man bash
IFS Das interne Feldtrennzeichen, das zum Teilen von Wörtern nach der Erweiterung und zum Teilen von Zeilen in Wörter mit dem Befehl read builtin verwendet wird. Der Standardwert ist "<Leerzeichen> <Tab> <Zeilenvorschub>".
Dies ist eine der internen Variablen von Bash. Es legt fest, wie Bash Felder oder Wortgrenzen erkennt, wenn Zeichenfolgen interpretiert werden.
Die Standardeinstellung ist Leerzeichen (Leerzeichen, Tabulator und Zeilenvorschub). Sie kann jedoch geändert werden, um beispielsweise eine durch Kommas getrennte Datendatei zu analysieren.
Lassen Sie mich zusätzlich zu den bisherigen tollen Antworten hinzufügen, dass IFS in Kombination mit set in einfachen Fällen sehr nützlich für effizientes und portables Parsen ist . Effizient, da die Verwendung von Subshells und Laichwerkzeugen wie grep oder sed vermieden wird:
resolutions="640x480,320x240"
xIFS=$IFS
IFS=','
for res in $resolutions; do
xxIFS=$IFS
IFS='x'
set -- $res
width=$1
height=$2
# handle width and height
IFS=$xxIFS
done;
IFS=$xIFS
Beachten Sie nur, dass wir den vorherigen Wert von IFS speichern und wiederherstellen müssen , um unerwünschte Brüche in anderen Teilen des Skripts zu vermeiden.