У меня проблемы с пониманием странного поведения: vi, кажется, добавляет новую строку (ASCII: LF, так как это система Unix ( AIX )) в конце файла, когда я НЕ специально его печатал.
Я редактирую файл как таковой в vi (стараясь не вводить новую строку в конце):
# 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.
Я ожидаю, что vi сохранит его «как есть», поэтому будет иметь 39 байтов: 10 символов ASCII в каждой из первых трех строк (цифры от 1 до 9, за которыми следует новая строка (LF в моей системе)) и только 9 в последней строка (символы от 1 до 9, без новой строки / LF).
Но появляется, когда я сохраняю его, это 40 байтов (вместо 39), и od показывает завершающий 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?
Если я создаю файл с помощью printf, делая то же самое, что и в vi, он работает как положено:
# ## 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.
Оба файла (foo (40 символов) и foo2 (39 символов) выглядят одинаково, если я снова открываю их с помощью ...
И если я открываю foo2 (39 символов, без завершающей строки) в vi и просто :wq
не редактирую его , он говорит, что записывает 40 символов, и появляется перевод строки!
У меня не может быть доступа к более новой версии vi (я делаю это в AIX, vi (не Vim ) версии 3.10, я думаю? (Без «-version» или других способов узнать это)).
# strings /usr/bin/vi | grep -i 'version.*[0-9]'
@(#) Version 3.10
Это нормально для vi (и, возможно, не в более поздней версии? Или Vim?), Чтобы тихо добавить новую строку в конце файла? (Я думал, что ~ указывает на то, что предыдущая строка НЕ заканчивалась символом новой строки.)
-
Изменить: некоторые дополнительные обновления и немного резюме, с большой благодарностью за ответы ниже:
vi тихо добавляет завершающий символ новой строки в тот момент, когда пишет файл, в котором его не было (если файл не пуст).
это происходит только во время написания! (т. е. до тех пор, пока вы: w, вы можете использовать: e, чтобы убедиться, что файл все еще находится в том же состоянии, в котором вы его открывали ... (т.е. он по-прежнему показывает "имя файла" [Последняя строка не завершена] N строка, символ M). Когда вы сохраняете, новая строка добавляется без предупреждения, без особого предупреждения (она говорит, сколько байтов она сохраняет, но в большинстве случаев этого недостаточно, чтобы знать, что была добавлена новая строка) (спасибо @jiliagre за то, что поговорили со мной о открыв сообщение vi, оно помогло мне найти способ узнать, когда действительно произойдет изменение)
Это (тихая коррекция) - поведение POSIX ! (см. @ barefoot-io answer для справок)
vi
версию или хотя бы понять ее происхождение, запустив :ve
команду.
ex
страницу руководства, где :ver
обычно описывается команда.