Ich habe Probleme, ein seltsames Verhalten zu verstehen: vi scheint eine neue Zeile (ASCII: LF, da es sich um ein Unix- System ( AIX ) handelt) am Ende der Datei hinzuzufügen , als ich sie NICHT speziell eingegeben habe.
Ich bearbeite die Datei als solche in vi (achte darauf, dass du am Ende keine neue Zeile eingibst):
# vi foo ## Which I will finish on the char "9" and not input a last newline, then `:wq`
123456789
123456789
123456789
123456789
~
~
## When I save, the cursor is just above the last "9", and no newline was added.
Ich erwarte, dass vi es "so wie es ist" speichert, um 39 Bytes zu haben: 10 ASCII-Zeichen in jeder der ersten drei Zeilen (Nummern 1 bis 9, gefolgt von einer neuen Zeile (LF auf meinem System)) und nur 9 in der letzten Zeile (Zeichen 1 bis 9, kein abschließender Zeilenumbruch / LF).
Aber es erscheint, wenn ich es speichere, es ist 40 Bytes (anstelle von 39), und od zeigt ein abschließendes LF :
# wc foo
4 4 40 foo ## I expected 39 here! as I didn't add the last newline
# od -a toto
0000000 1 2 3 4 5 6 7 8 9 lf 1 2 3 4 5 6
0000020 7 8 9 lf 1 2 3 4 5 6 7 8 9 lf 1 2
0000040 3 4 5 6 7 8 9 lf
0000050
## An "lf" terminates the file?? Did vi add it silently?
Wenn ich die Datei mit einem printf erstelle, der genau das tut, was ich in vi getan habe, funktioniert es wie erwartet:
# ## I create a file with NO newline at the end:
# printf "123456789\n123456789\n123456789\n123456789" > foo2
# wc foo2 ## This one is as expected: 39 bytes, exactly as I was trying to do above with vi.
3 4 39 foo ## As expected, as I didn't add the last newline
## Note that for wc, there are only three lines!
## (So wc -l doesn't count lines; it counts the [newline] chars... Which is rather odd.)
# root@SPU0WMY1:~ ## od -a foo2
0000000 1 2 3 4 5 6 7 8 9 lf 1 2 3 4 5 6
0000020 7 8 9 lf 1 2 3 4 5 6 7 8 9 lf 1 2
0000040 3 4 5 6 7 8 9
0000047 ## As expected, no added LF.
Beide Dateien (foo (40 Zeichen) und foo2 (39 Zeichen) sehen genauso aus, wenn ich sie mit vi ...
Und wenn ich foo2 (39 Zeichen, kein abschließender Zeilenumbruch) in vi öffne und einfach auf die :wq
Bearbeitung verzichte, werden 40 Zeichen geschrieben und der Zeilenvorschub wird angezeigt!
Ich kann nicht auf ein neueres vi zugreifen (ich mache das unter AIX, vi (nicht Vim ) Version 3.10, glaube ich? (Keine "-version" oder andere Mittel, um es zu wissen)).
# strings /usr/bin/vi | grep -i 'version.*[0-9]'
@(#) Version 3.10
Ist es normal, dass vi (und möglicherweise nicht in einer neueren Version? Oder Vim?) Am Ende einer Datei stillschweigend eine neue Zeile hinzufügt? (Ich dachte, das ~ deutet darauf hin, dass die vorherige Zeile NICHT mit einer neuen Zeile endet.)
-
Bearbeiten: einige zusätzliche Updates und eine kleine Zusammenfassung, mit großem Dank an die Antworten unten:
vi Fügen Sie stillschweigend eine abschließende Zeile hinzu, wenn eine Datei geschrieben wird, der diese fehlte (es sei denn, die Datei ist leer).
Dies geschieht nur zum Zeitpunkt des Schreibens! (dh, bis Sie: w, können Sie: e verwenden, um zu überprüfen, ob die Datei noch in dem Zustand ist, in dem Sie sie geöffnet haben ... (dh, es wird immer noch "Dateiname" angezeigt. [Letzte Zeile ist nicht vollständig.] N Zeile, M Zeichen). Wenn Sie speichern, wird eine neue Zeile stillschweigend ohne besondere Warnung hinzugefügt (es wird zwar angegeben, wie viele Bytes gespeichert werden, dies reicht jedoch in den meisten Fällen nicht aus, um zu wissen, dass eine neue Zeile hinzugefügt wurde) (danke an @jiliagre, dass Sie mit mir über das gesprochen haben Nachdem ich die vi-Nachricht geöffnet habe, habe ich herausgefunden, wann die Änderung tatsächlich eintritt.
Dies (stille Korrektur) ist POSIX- Verhalten! (Referenzen finden Sie unter @ barefoot-io answer)
vi
Version oder zumindest einen Hinweis auf die Herkunft erhalten, indem Sie den:ve
Befehl ausführen.ex
Handbuchseite entfernt, auf der der:ver
Befehl normalerweise dokumentiert ist.Antworten:
Dies ist das erwartete
vi
Verhalten.Ihre Datei enthält eine unvollständige letzte Zeile, so dass es sich streng genommen (dh gemäß dem POSIX-Standard) nicht um eine Textdatei, sondern um eine Binärdatei handelt.
vi
Dies ist ein Textdatei-Editor, kein Binär-Editor. Er behebt ihn ordnungsgemäß, wenn Sie ihn speichern.Dies ermöglicht es anderen Textdatei-Tools und dergleichen
wc
,sed
die erwartete Ausgabe bereitzustellen. Beachten Sie, dassvi
zu diesem Thema nicht geschwiegen wird:Beachten
vi
Sie, dass Sie den:ve
Befehl verwenden können , um einige Hinweise zu erhalten, welche Version Sie ausführen. Es zeigt, dass ich hier einen älteren SVR4 verwende, definitiv nichtvim
:Anscheinend heißt es bei Ihnen:
vi
Dies bedeutet wahrscheinlich, dass AIX auf SVR3-Quellcode basiert.In jedem Fall sind dieses Verhalten und die
[Incomplete last line]
Warnmeldungvi
seit mindestens 1979 und AFAIK im früheren Quellcode von Bill Joy enthalten und in allen Zweigen enthalten, die mit System V-Quellcode-Releases erstellt wurden, aus denen proprietäre Unix-Versionen wie AIX erstellt wurden.Chronologisch gesehen ist dieses Verhalten dann nicht eine Konsequenz der POSIX-Konformität, sondern eher eine Konsequenz von Bill Joys ursprünglicher Entscheidung, Benutzern beim Bearbeiten gefälschter Textdateien behilflich zu sein, und ein Jahrzehnt später der Entscheidung des POSIX-Komitees, diese Toleranz beizubehalten.
Wenn Sie
ed
anstelle von verwendenvi
, werden Sie feststellen, dass das erstere ausführlicher über das Problem ist, zumindest wenned
es aus SVR3 oder einem neueren Quellenzweig stammt:Beachten Sie auch, dass eine leere Datei eine gültige Textdatei ist, die zufällig Nullzeilen enthält. Da dann keine nicht abgeschlossene Zeile zu reparieren ist,
vi
wird beim Speichern der Datei keine neue Zeile angehängt.quelle
vi
genau wie das OP, obwohl auf einem anderen Unix. Dies ist nicht der einevim
oder andere Klon. Antwort aktualisiert, um dies zu klären.vi
Implementierung verwendet. Möglicherweise SVR3. Sind Sie sicher, dass[Incomplete last line]
beim Öffnen der Datei keine Meldung angezeigt wird?vi
Implementierung angezeigt werden kann : www-01.ibm.com/support/docview.wss?uid=isg1IZ27694POSIX erfordert dieses Verhalten, es ist also in keiner Weise ungewöhnlich.
Aus dem POSIX vi-Handbuch :
Dem Weg zum POSIX ex-Handbuch folgen :
Der Abschnitt OUTPUT FILES des vi-Handbuchs leitet auch Folgendes weiter:
Ein Paar POSIX-Definitionen:
Diese Definitionen im Kontext dieser Handbuchseitenauszüge bedeuten, dass eine konforme ex / vi-Implementierung eine fehlerhafte Textdatei akzeptieren muss, wenn die einzige Deformität dieser Datei eine fehlende letzte Zeile ist. Beim Schreiben des Puffers dieser Datei muss das Ergebnis eine gültige Textdatei sein.
Während in diesem Beitrag auf die Ausgabe 2013 des POSIX-Standards verwiesen wurde, erscheinen die entsprechenden Bestimmungen auch in der viel älteren Ausgabe von 1997 .
Wenn Sie die Newline Appension von Ex als unerwünscht empfinden, werden Sie sich von der intoleranten Ausgabe von Seventh Edition UNIX (1979) zutiefst verletzt fühlen. Aus dem Handbuch :
quelle
ex
(weiß nicht, wie er heißt), ich denke, POSIX-Spezifikationen sind so gut wie erwartet. ;) Bis zu diesem Punkt der "Originalquelle" am nächsten, obwohl es wahr ist, begannen sie als mehr oder weniger Beschreibung der vorhandenen Funktionalität.ex
wurde von Bill Joy und Chuck Alley ( web.cecs.pdx.edu/~kirkenda/joy84.html ) mitgeschrieben . Ich stelle die POSIX-Spezifikationen nicht in Frage und die Tatsache, dass aktuellevi
Releases folgen, ich erkläre nur das Verhalten lange älter als es ist.Ich kann mich an kein anderes Verhalten erinnern, bei dem eine neue Zeile am Ende einer Datei eingefügt wurde (
vi
seit Mitte der 80er Jahre).Das
~
bedeutet, dass eine Zeile auf dem Bildschirm nicht Teil des Texts ist und die Datei nicht in einer neuen Zeile endet. (Es kann schwierig werden, Fehler zu verfolgen, wenn Sie in~
die letzte Zeile der Shell-Skripte ein setzen.) Wenn Sie eine kurze Datei mit einem Zeilenumbruch am Ende laden, werden Sie sich~
selbst sehen und beweisen, dass Ihr Gedanke darauf hindeutet, dass der Text nicht mit Zeilenumbruch endet.quelle
ed
) würden Sie Linien erstellen und diese bearbeiten, nicht durch Anhängen von Zeichen. Ich habe immer auch an vi als zeilenorientierten Editor gedacht. Aber ich verstehe deine Überraschung.Text, dem die ultimative neue Zeile durch eine Shell-
while
Schleife nicht ordnungsgemäß fehlt, führt dazu, dass die letzte Zeile stillschweigend verworfen wird.Sicherzustellen, dass es einen endgültigen Zeilenumbruch gibt, ist die richtige und vernünftige Vorgabe. Die andere Möglichkeit besteht darin, zu wissen und die Zeit zu haben, den gesamten Shell-Code zu prüfen, der Text berührt, dem die letzte Zeile fehlt, oder zu riskieren, die letzte Zeile des Texts zu verlieren.
quelle