Das Problem liegt nicht in cat
, noch in for
Schleife an sich; es ist in der Verwendung von Backquotes. Wenn Sie entweder schreiben:
for i in `cat file`
oder (besser):
for i in $(cat file)
oder (in bash
):
for i in $(<file)
Die Shell führt den Befehl aus und erfasst die Ausgabe als Zeichenfolge, wobei die Wörter an den Zeichen in $IFS
getrennt werden . Wenn Sie Zeilen eingeben möchten, geben Sie $i
ein , müssen Sie entweder mit IFS
herumspielen oder verwenden Sie den while
Schleife. Die while
Schleife ist besser, wenn die Gefahr besteht, dass die verarbeiteten Dateien groß werden; es muss nicht die ganze Datei auf einmal in den Speicher eingelesen werden, im Gegensatz zu den Versionen, die $(...)
verwenden .
IFS='
'
for i in $(<file)
do echo "$i"
done
Die Anführungszeichen um die "$i"
sind generell eine gute Idee. In diesem Zusammenhang mit dem modifizierten $IFS
, es ist eigentlich nicht kritisch, aber gute Gewohnheiten sind trotzdem gute Gewohnheiten. Es ist im folgenden Skript von Bedeutung:
old="$IFS"
IFS='
'
for i in $(<file)
do
(
IFS="$old"
echo "$i"
)
done
wenn die Datendatei mehrere Leerzeichen zwischen Wörtern enthält:
$ cat file
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
$
Ausgabe:
$ sh bq.sh
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
$
Ohne die doppelten Anführungszeichen:
$ cat bq.sh
old="$IFS"
IFS='
'
for i in $(<file)
do
(
IFS="$old"
echo $i
)
done
$ sh bq.sh
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
$
Sie können IFS
verwenden Variable, um einen Zeilenumbruch als Feldtrenner festzulegen:
IFS=$'\n'
for i in `cat file`
do
echo $i
done
die for-Schleife gekoppelt mit einer Änderung des internen Feldtrennzeichens (IFS) liest die Datei wie vorgesehen
für eine Eingabe
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
For-Schleife gekoppelt mit einer IFS-Änderung
old_IFS=$IFS
IFS=$'\n'
for i in `cat file`
do
echo $i
done
IFS=$old_IFS
ergibt
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma