2030 Stimmen

Warum sollten Textdateien mit einem Zeilenumbruch enden?

Ich nehme an, dass jeder hier mit dem Sprichwort vertraut ist, dass alle Textdateien mit einem Zeilenumbruch enden sollten. Ich kenne diese "Regel" schon seit Jahren, aber ich habe mich immer gefragt, warum?

20voto

jrw32982 Punkte 568

Zusätzlich zu den oben genannten praktischen Gründen würde es mich nicht überraschen, wenn die Erfinder von Unix (Thompson, Ritchie, et al.) oder ihre Multics-Vorgänger erkannt hätten, dass es einen theoretischen Grund gibt, Zeilenterminatoren anstelle von Zeilentrennern zu verwenden: Mit Zeilenterminatoren kann man alle möglichen Zeilendateien kodieren. Mit Zeilentrennern gibt es keinen Unterschied zwischen einer Datei mit null Zeilen und einer Datei mit einer einzigen leeren Zeile; beide werden als eine Datei mit null Zeichen kodiert.

Das sind also die Gründe:

  1. Denn so ist es in POSIX definiert.
  2. Denn einige Werkzeuge erwarten sie oder verhalten sich ohne sie "falsch". Zum Beispiel, wc -l zählt eine letzte "Zeile" nicht, wenn sie nicht mit einem Zeilenumbruch endet.
  3. Weil es einfach und bequem ist. Unter Unix, cat funktioniert einfach, und zwar ohne Komplikationen. Es werden einfach die Bytes jeder Datei kopiert, ohne dass eine Interpretation erforderlich ist. Ich glaube nicht, daß es ein DOS-Äquivalent gibt zu cat . Verwendung von copy a+b c wird am Ende die letzte Zeile der Datei a mit der ersten Zeile der Datei b .
  4. Denn eine Datei (oder ein Stream) mit null Zeilen kann von einer Datei mit einer leeren Zeile unterschieden werden.

13voto

Marc Gravell Punkte 970173

Vermutlich hat ein Parsing-Code einfach erwartet, dass er dort vorhanden ist.

Ich bin mir nicht sicher, ob ich das als "Regel" bezeichnen würde, und es ist sicherlich nicht etwas, an das ich mich religiös halte. Der meiste vernünftige Code weiß, wie man Text (einschließlich Kodierungen) zeilenweise analysiert (mit oder ohne Zeilenende), mit oder ohne Zeilenumbruch in der letzten Zeile.

In der Tat - wenn Sie mit einer neuen Zeile enden: Gibt es (theoretisch) eine leere letzte Zeile zwischen EOL und EOF? Eine Überlegung wert...

12voto

l0b0 Punkte 51652

Es gibt auch ein praktisches Programmierproblem mit Dateien ohne Zeilenumbrüche am Ende: Die read Bash eingebaut (ich weiß nicht, ob andere read Implementierungen) funktioniert nicht wie erwartet:

printf $'foo\nbar' | while read line
do
    echo $line
done

Dies druckt seulement foo ! Der Grund dafür ist, dass, wenn read auf die letzte Zeile stößt, schreibt es den Inhalt in $line gibt aber den Exit-Code 1 zurück, weil er EOF erreicht hat. Dies bricht die while Schleife, so dass wir nie die echo $line Teil. Wenn Sie diese Situation bewältigen wollen, müssen Sie Folgendes tun:

while read line || [ -n "${line-}" ]
do
    echo $line
done < <(printf $'foo\nbar')

Das heißt, die echo si le read ist wegen einer nicht leeren Zeile am Ende der Datei fehlgeschlagen. Natürlich wird in diesem Fall ein zusätzlicher Zeilenumbruch in der Ausgabe erscheinen, der in der Eingabe nicht enthalten war.

9voto

Warum sollten (Text-)Dateien mit einem Zeilenumbruch enden?

Wie von vielen gut ausgedrückt, denn:

  1. Viele Programme verhalten sich nicht gut oder scheitern ohne sie.

  2. Selbst Programmen, die eine Datei gut verarbeiten können, fehlt ein Ende '\n' Die Funktionalität des Tools entspricht möglicherweise nicht den Erwartungen des Benutzers, die in diesem Fall unklar sein können.

  3. Programme selten nicht zulassen endgültig '\n' (Mir sind keine bekannt).


Dies wirft jedoch die nächste Frage auf:

Was soll der Code bei Textdateien ohne Zeilenumbruch tun?

  1. Das Wichtigste - Schreiben Sie keinen Code, der davon ausgeht, dass eine Textdatei mit einem Zeilenumbruch endet. . Angenommen, eine Datei einem Format entspricht, führt zu Datenbeschädigung, Hackerangriffen und Abstürzen. Beispiel:

    // Bad code
    while (fgets(buf, sizeof buf, instream)) {
      // What happens if there is no \n, buf[] is truncated leading to who knows what
      buf[strlen(buf) - 1] = '\0';  // attempt to rid trailing \n
      ...
    }
  2. Wenn das letzte Wort am Ende '\n' benötigt wird, weisen Sie den Benutzer auf sein Fehlen und die ergriffene Maßnahme hin. D.h., überprüfen Sie das Format der Datei. Hinweis: Dies kann eine Begrenzung der maximalen Zeilenlänge, der Zeichenkodierung usw. beinhalten.

  3. Definieren Sie klar und dokumentieren Sie, wie der Code mit einer fehlenden Endung umgeht. '\n' .

  4. Möglichst nicht, erzeugen eine Datei, bei der die Endung fehlt '\n' .

7voto

Arpit Punkte 12689

Es ist schon sehr spät, aber ich hatte gerade einen Fehler bei der Dateiverarbeitung, und der kam daher, dass die Dateien nicht mit einem leeren Zeilenumbruch beendet wurden. Wir verarbeiteten Textdateien mit sed y sed ließ die letzte Zeile in der Ausgabe aus, was zu einer ungültigen json-Struktur führte und den Rest des Prozesses in einen Fehlerzustand versetzte.

Alles, was wir taten, war:

Es gibt eine Beispieldatei: foo.txt mit einigen json Inhalt darin.

[{
    someProp: value
},
{
    someProp: value
}] <-- No newline here

Die Datei wurde auf einem Windows-Computer erstellt, und Fensterskripte verarbeiteten diese Datei mit PowerShell-Befehlen. Alles gut.

Wenn wir dieselbe Datei mit sed Befehl sed 's|value|newValue|g' foo.txt > foo.txt.tmp

Die neu erstellte Datei wurde

[{
    someProp: value
},
{
    someProp: value

und schon schlug der Rest der Prozesse wegen des ungültigen JSON fehl.

Es ist also immer eine gute Praxis, die Datei mit einer neuen Leerzeile zu beenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X