GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Warum können Sie cat nicht verwenden, um eine Datei Zeile für Zeile zu lesen, wobei jede Zeile Trennzeichen hat

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

Linux
  1. Warum kann Rm schreibgeschützte Dateien entfernen?

  2. Können Sie Anker ^ $ mit Ls verwenden?

  3. Warum können Dateien nicht von Inode manipuliert werden?

  4. Wie kann ich in jedem Ordner eine Datei erstellen?

  5. Wo ist die Header-Datei <conio.h> unter Linux? Warum kann ich <conio.h> nicht finden?

Warum ich unter Linux exa anstelle von ls verwende

So lesen Sie Dateien Zeile für Zeile in Bash

So lesen Sie eine Datei Zeile für Zeile in Bash

Fügen Sie am Anfang jeder Zeile eine Präfixzeichenfolge hinzu

Warum wird select unter Linux verwendet

Warum lesen einige eingebaute Shells nicht die ganze Zeile aus der Datei in `/proc`?