I have trouble understanding a weird behavior: vi seems to add a newline (ASCII: LF, as it is a Unix (AIX) system) at the end of the file, when I did NOT specifically type it.
I edit the file as such in vi (taking care to not input a newline at the end):
# 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.
I expect vi to save it "as is", so to have 39 bytes: 10 ASCII characters on each of the first three lines (numbers 1 to 9, followed by a newline (LF on my system)) and only 9 on the last line (characters 1 to 9, no terminating newline/LF).
But it appears when I save it it is 40 bytes (instead of 39), and od shows a terminating 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?
If I create the file with a printf doing exactly what I did inside vi, it works as expected:
# ## 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.
Both files (foo (40 characters) and foo2 (39 characters) appear exactly the same if I re-open them with vi...
And if I open foo2 (39 characters, no terminating newline) in vi and just do :wq
without editing it whatsoever, it says it writes 40 chars, and the linefeed appears!
I can't have access to a more recent vi (I do this on AIX, vi (not Vim) version 3.10 I think? (no "-version" or other means of knowing it)).
# strings /usr/bin/vi | grep -i 'version.*[0-9]'
@(#) Version 3.10
Is it normal for vi (and perhaps not in more recent version? Or Vim?) to silently add a newline at the end of a file? (I thought the ~ indicated that the previous line did NOT end with a newline.)
--
Edit: some additional updates and a bit of a summary, with a big thanks to the answers below :
vi silently add a trailing newline at the moment it writes a file that lacked it (unless file is empty).
it only does so at the writing time! (ie, until you :w, you can use :e to verify that the file is still as you openened it... (ie: it still shows "filename" [Last line is not complete] N line, M character). When you save, a newline is silently added, without a specific warning (it does say how many bytes it saves, but this is in most cases not enough to know a newline was added) (thanks to @jiliagre for talking to me about the opening vi message, it helped me to find a way to know when the change really occurs)
This (silent correction) is POSIX behavior! (see @barefoot-io answer for references)
vi
version or at least a clue about its origin by running the:ve
command. – jlliagre Feb 17 '16 at 21:00strings
. The behavior is well-known to vi-users. – Thomas Dickey Feb 17 '16 at 21:12ve
(version) command forex
. I was commenting on the behavior of newline, which OP also was unaware. A good manual would help, but AIX manual pages are not helpful to OP. – Thomas Dickey Feb 18 '16 at 09:37ex
manual page where the:ver
command is normally documented. – jlliagre Feb 18 '16 at 11:19:ve
indeed works! (but AIX man vi is lacking this information). Thanks.. in vi,:ve
returns:Version 3.10
– Olivier Dulac Feb 18 '16 at 16:10Edit : thanks to ... and ... answers, that I can summarize as:
, which got lost ?! (maybe because it started with a bracket?)... thanks for pointing it out. I'll try to re-edit it, and move the whole thing to the bottom of the question (or maybe remove it entirely) – Olivier Dulac Feb 24 '16 at 18:33:e!
to have it display its status: it still complains about the missing terminating newline). So the first 2 bullets are not a duplicate, they each add something different. And the first line is no substitute for the answers below, but is needed to read the rest of the edit (then the person will proceed to the real answers, abd get a lot more details and explanation, and concrete answers instead of just behaviours) – Olivier Dulac Feb 24 '16 at 19:04