Am Anfang eines Bash-Shell-Skripts steht die folgende Zeile:
IFS=$'\n'
Welche Bedeutung hat diese Symbolsammlung?
IFS=$'\n'
ist ein bashism (+ andere Schalen, verwenden ANSI-C Zitiert für Abhilfen siehe stackoverflow.com/questions/10748703/...
Am Anfang eines Bash-Shell-Skripts steht die folgende Zeile:
IFS=$'\n'
Welche Bedeutung hat diese Symbolsammlung?
IFS=$'\n'
ist ein bashism (+ andere Schalen, verwenden ANSI-C Zitiert für Abhilfen siehe stackoverflow.com/questions/10748703/...
Antworten:
IFS
steht für "internes Feldtrennzeichen". Es wird von der Shell verwendet, um zu bestimmen, wie die Wortteilung durchgeführt wird, dh wie Wortgrenzen erkannt werden.
Versuchen Sie dies in einer Shell wie bash (andere Shells können dies anders handhaben, zum Beispiel zsh):
mystring="foo:bar baz rab"
for word in $mystring; do
echo "Word: $word"
done
Der Standardwert für IFS
besteht aus Leerzeichen (um genau zu sein: Leerzeichen, Tabulator und Zeilenvorschub). Jedes Zeichen kann eine Wortgrenze sein. Daher wird mit dem Standardwert von IFS
die obige Schleife gedruckt:
Word: foo:bar
Word: baz
Word: rab
Mit anderen Worten, die Shell denkt, dass Leerzeichen eine Wortgrenze sind.
Versuchen Sie nun die Einstellung, IFS=:
bevor Sie die Schleife ausführen. Dieses Mal lautet das Ergebnis:
Word: foo
Word: bar baz rab
Jetzt teilt sich die Shell auch mystring
in Wörter auf - aber jetzt wird nur ein Doppelpunkt als Wortgrenze behandelt.
Das erste Zeichen von IFS
ist special: Es wird verwendet, um Wörter in der Ausgabe zu begrenzen, wenn die spezielle $*
Variable verwendet wird (Beispiel aus dem Advanced Bash Scripting Guide , in dem Sie auch weitere Informationen zu speziellen Variablen wie dieser finden):
$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
w:x:y:z
Vergleichen mit:
$ bash -c 'set w x y z; IFS="-:;"; echo "$*"'
w-x-y-z
Beachten Sie, dass in beiden Beispielen wird die Schale noch alle Zeichen behandeln :
, -
und ;
als Wortgrenzen. Das einzige, was sich ändert, ist das Verhalten von $*
.
Ein weiterer wichtiger Aspekt ist die Behandlung des so genannten "IFS-Whitespace" . Grundsätzlich werden IFS
führende und nachfolgende Leerzeichen , sobald sie Leerzeichen enthalten, von der zu teilenden Zeichenfolge entfernt, bevor sie verarbeitet werden. Eine Folge von aufeinanderfolgenden Leerzeichen begrenzt die Felder ebenfalls. Dies gilt jedoch nur für die Whitespace-Zeichen, die tatsächlich in vorhanden sind IFS
.
Betrachten wir zum Beispiel die Zeichenfolge "a:b:: c d "
(Leerzeichen am Ende und zwei Leerzeichen zwischen c
und d
).
IFS=:
ihm würde in vier Felder aufgeteilt werden: "a"
, "b"
, ""
(leere Zeichenkette) und " c d "
(wieder zwei Räume zwischen c
und d
). Beachten Sie das führende und nachfolgende Leerzeichen im letzten Feld.IFS=' :'
wäre es in fünf Felder unterteilt werden: "a"
, "b"
, ""
(leere Zeichenkette), "c"
und "d"
. Kein führendes und nachfolgendes Leerzeichen.Beachten Sie, wie im zweiten Beispiel mehrere aufeinanderfolgende Leerzeichen zwei Felder voneinander trennen, während dies bei mehreren aufeinanderfolgenden Doppelpunkten nicht der Fall ist (da es sich nicht um Leerzeichen handelt).
Was IFS=$'\n'
ist , dass eine ksh93
Syntax auch unterstützt bash
, zsh
, mksh
und FreeBSD sh
(mit Variationen zwischen allen Schalen). Zitieren der Bash-Manpage:
Wörter der Form $ 'string' werden speziell behandelt. Das Wort wird zu "Zeichenfolge" erweitert, wobei mit einem Backslash versehene Zeichen gemäß dem ANSI C-Standard ersetzt werden.
\n
ist die Escape-Sequenz für eine neue Zeile und wird daher IFS
auf ein einzelnes Zeichen für eine neue Zeile festgelegt.
bash
Skriptanleitung oder was auch immer. In der Hauptsache fehlen die Informationen, die auf solchen Links verfügbar sind, in wichtigen Punkten. Auf jeden Fall fehlen also zwei wichtige Punkte beim Aufteilen der Shell - Globbing und IFS-Whitespace.
unset IFS
eine Shell ganz anders verhält als IFS=
. Auch das erste Byte in IFS ist etwas Besonderes "${named_array[*]}"
- aber es spielt keine
$IFS
ist eine der beiden Hauptaufgaben, die beim Erweitern einer Variablen ohne Anführungszeichen im Listenkontext ausgeführt wird (dies ist der split
Teil des split+glob
Operators). Der andere ist am Fressen. Wenn Sie die Arbeitsteilung verwenden, müssen Sie im Allgemeinen ein Problem set -f
lösen, um das glob
Teil zu deaktivieren .
$IFS
wird auch vom read
eingebauten Befehl verwendet
In einfachen Anführungszeichen werden einige Zeichen speziell ausgewertet. Beispielsweise \n
wird in eine neue Zeile übersetzt.
Diese bestimmte Zeile weist der Variablen IFS also eine neue Zeile zu. IFS wiederum ist eine spezielle Variable in bash: Internal Field Separator. Wie man bash
gesagt es
wird zum Teilen von Wörtern nach der Erweiterung und zum Teilen von Zeilen in Wörter mit dem
read
eingebauten Befehl verwendet. Der Standardwert ist<space><tab><newline>
.
dollared single quotes
die sich von einfachen einfachen Anführungszeichen unterscheidet.
Kurz gesagt, IFS=$'\n'
ordnen Sie \n
der Variablen einen Zeilenvorschub zu IFS
.
$'string'
construct ist ein Zitiermechanismus, mit dem ANSI C-ähnliche Escape-Sequenzen dekodiert werden. Diese Syntax stammt aus ksh93
und war tragbar moderne Shell wie bash
, zsh
, pdksh
, busybox sh
.
Diese Syntax wird von POSIX nicht definiert, wurde jedoch für SUS-Problem 7 akzeptiert .
Ich zu erklären , bevorzugt $IFS
über Beispiel:
Suppsoe Sie wollen cp oder mv oder eine andere Datei verarbeitend, IFS leer von defualt ist, wenn Sie Ihre Dateien Meta - Zeichen oder Platz haben , wie zum Beispiel:
Linux Administration.pdf
oder Free Software Fundation.ogg
, sicher werden Sie probelm haben, denn: Linux ein betrachten Separater Parameter und Administartion betrachten einen separaten Parameter. So hat Bash built-in variable
, dann können Sie initialisieren IFS==$(echo -en "\n\b")
, dann Bash verwerfen alle Metazeichen und Leerzeichen zwischen Dateinamen, zum Beispiel:
#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
mymusicdir=~/test/dd
find $mymusicdir -name "*" -execdir rename 's/ /_/g' "{}" +
IFS=$SAVEIFS