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:
IFSsteht 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.InputInternal Field Separator\nforIFS
Übrigens, von der Antwort, die Sie gepostet haben, ist die zweite Lösung die empfohlene ...
Wie @jasonwryan bemerkt hat, ist es nicht Inputaber Internal. Name Inputkam von awkdem es auch OFS- gibt Output Field Separator.
Sfü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 Sis 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 FSoder der sParametererweiterung von zsh.
IFSist nicht direkt mit dem Schleifen verbunden, sondern mit dem Teilen von Wörtern. IFSLegt indirekt fest, wie die Ausgabe des Befehls in Teile aufgeteilt wird, über die die Schleife iteriert.
Wenn Sie eine ungeschützte Variablensubstitution $foooder 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.$IFSwird, wird als Worttrennzeichen betrachtet. Zum Beispiel IFS=":"; foo="12:34::78"; echo $fooAusdrucke 12 34 78(mit zwei Leerzeichen zwischen 34und 78, da es ein leeres Wort gibt).foo="*"; echo $foodie 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 IFSist space, tab und newline . Wenn also foozwei Zeilen ausgedruckt werden hello worldund howdydann der Schleifenkörper mit x=hello, dann x=worldund ausgeführt wird x=howdy. Wenn IFSexplizit geändert wird, um nur eine neue Zeile zu enthalten, wird die Schleife für hello worldund ausgeführt howdy. Wenn IFSgeä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.