Почему Vim добавляет новую строку? Это соглашение?


22

Если я открываю Vim и печатаю, itest<Esc>:wqя получаю файл, в котором нет новых строк в Vim, но, похоже, в нем есть новая строка :

$ vim -u NONE test.txt
$ cat test.txt | hd
00000000  74 65 73 74 0a                    |test.|
00000005

Если я открываю Vim и печатаю, itest<Return><Esc>:wqя получаю файл, в котором есть одна новая строка в Vim, но две строки в коде:

$ rm test.txt
$ vim -u NONE test.txt
$ cat test.txt | hd
00000000  74 65 73 74 0a 0a                 |test..|
00000006

Обратите внимание, что я открываю Vim с помощью -u NONEлокальной конфигурации, которая не используется. Обратите внимание, что это может быть связано с моим предыдущим вопросом .

Это моя системная информация:

$ uname -a
Linux awsAlpha 3.2.0-60-virtual #91-Ubuntu SMP Wed Feb 19 04:13:28 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ vim --version
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled May  4 2012 04:25:35)
Included patches: 1-429
Modified by pkg-vim-maintainers@lists.alioth.debian.org
Compiled by buildd@

Я могу подтвердить точно такое же поведение в этой системе:

$ uname -a
Linux bruno 3.5.0-48-generic #72-Ubuntu SMP Mon Mar 10 23:18:29 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ vim --version
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Oct 26 2012 16:45:33)
Included patches: 1-547
Modified by pkg-vim-maintainers@lists.alioth.debian.org
Compiled by buildd@

Почему Vim добавляет новую строку? Это соглашение?

Вот некоторые пояснения по поводу hdкоманды, установленной на Ubuntu Server:

$ man hd | head -4
HEXDUMP(1)            BSD General Commands Manual            HEXDUMP(1)

NAME
     hexdump, hd — ASCII, decimal, hexadecimal, octal dump

8
Кажется, это соглашение. Вот как это отключить, если хотите. Вот история этого.
jliv902

Ответы:


28

Соглашение для текстовых файлов Unix заключается в том, что каждая строка заканчивается новой строкой, а новые строки являются разделителями строк, а не разделителями строк.

Когда Vim сохраняет буфер как файл, он заканчивает каждую строку последовательностью конца строки для этого формата файла, который для Unix является новой строкой. Видеть

:help 'fileformat'

Если вы используете инструменты обработки текста Unix, лучше придерживаться этого соглашения. Однако, если вам нужно не ставить символ новой строки в конце последней строки файла, вы можете сделать это. Vim считает такие файлы «двоичными». Видеть

:help 'binary'
:help edit-binary

1
о, это интересно Так что кроме знаменитых \ r \ n vs \ n. Windows использует разделители строк, а Unix использует разделители строк? и это где-нибудь задокументировано? Я знаю, что это здесь определено, по-видимому, применимо к unix "ISO / IEC 9899: 2011, раздел §7.21.2. Потоки говорят: текстовый поток - это упорядоченная последовательность символов, состоящая из строк, каждая строка состоит из нуля или более символов плюс завершающий новый -линейный персонаж "
barlop

но где задокументировано, что в windows используется разделитель строк?
Бароп

2

Vim не добавляет ничего, что ты сам не положил туда.

Символ «новой строки» не является «новой строкой», и оба примера совершенно нормальны:

  • в первом файл содержит только одну строку, поэтому вы получаете один символ «новой строки»,
  • во втором файле содержит две строки, поэтому вы получаете два символа «новой строки».

2
Это добавляет новую строку. Проверьте это следующим образом:, printf "\x41" > /tmp/test.txtзатем убедитесь, что он имеет только один символ «A» с xxd /tmp/test.txt. Теперь vim /tmp/test.txt<ENTER>:wq. Проверьте еще раз, чтобы увидеть файл, имеющий два байта: 'A \ n'.
Руслан

Строки заканчиваются символом новой строки. У вас есть одна строка, поэтому у вас есть один символ новой строки.
Ромен

Ну, а printfздесь у меня не было хорошо сформированных «линий». После VIM у меня есть один. Таким образом, это добавляет то, что я не положил туда.
Руслан

То, что вы printfне линия, если вы не добавите \n. Будучи текстовым редактором, Vim работает со строками по умолчанию, и любой текст, который вы вставляете в файл, находится , по крайней мере, на строке, если вы явно не скажете Vim не делать этого.
Ромен

2

Неопределенные текстовые файлы являются злыми по нескольким причинам; вот тот, который я еще не видел упомянутым:

В гипотетическом мире, где текстовые файлы без завершающей новой строки являются приемлемыми, не будет никакой разницы между файлом, содержащим 0 строк, и файлом, содержащим 1 пустую строку. Они оба будут представлены 0-байтовым файлом.

Неспособность решить, сколько строк в файле будет плохой.


Текстовые файлы в не-Unix системах содержат ноль или более полных строк, а также неполную строку из ноля или более символов. Пустой файл не содержит пустой строки; он содержит ноль полных строк и частичную строку из нулевых символов. Где двусмысленность?
суперкат

Эта «частичная линия» - неприятное понятие. Вы не можете иметь нигде кроме конца файла, и вы не можете создать файл, который не имеет «частичной строки». Это добавляет больше разрыва к конкатенации файлов - даже если вы вставляете новую строку между файлами, вы в конечном итоге получаете что-то, что семантически не эквивалентно исходной паре файлов (потому что с 2 файлами у вас было 2 частичные строки, и одна из них стала чем-то вроде разные.) Неэлегантное предложение.

Тот факт, что объединение файлов приведет к тому, что любая частичная строка в конце первого будет добавлена ​​к следующему файлу, обычно является странным в тех случаях, когда оба файла содержат полные строки (иногда бывает полезно объединить файлы, которые не содержат полных строк). ), Но что есть, то есть. Unix не запрещает создание текстовых файлов, заканчивающихся частичными строками, и я считаю, что объединение таких файлов будет вести себя как в MSDOS. Разница, на мой взгляд, в том, что многие редакторы на базе DOS исторически придерживались мнения, что загрузка и немедленное сохранение файла должны привести к появлению нового файла ...
supercat

... который немного идентичен старому (зарегистрированные пользователи ранних версий PC-Write получили указание использовать его для открытия копии исполняемого файла, перехода в режим перезаписи, поиска определенной строки и замены ее на свою серийный номер!). Принудительное завершение файлов с новой строкой при их сохранении нарушит это ограничение.
суперкат

2

Vim 8.0 теперь обеспечивает это с помощью fixeolопции. В частности, если вы делаете:

:set nofixeol

тогда Vim не добавит завершающий символ новой строки в конце последней строки, если у файла его еще нет.

Это может пойти в плагин типа файла, или, возможно, даже ваш .vimrc.

(Это улучшение, :set binaryпотому что оно влияет только на последний символ переноса строки, в то binaryже время также меняет кучу других поведений, которые вы, вероятно, не хотите, если вы на самом деле не редактируете двоичный файл.)

Вновь созданный файл по-прежнему будет иметь завершающий символ перевода строки по умолчанию. Вы можете изменить это (и переключить файл, в котором уже есть последний перевод строки на отсутствие такового), дополнительно выполнив:

:set noeol

Это должно быть установлено специально для каждого файла, который вы хотите изменить: загрузка файла в буфер всегда eolбудет соответствовать текущему состоянию файла.


1

С помощью команды 'j' вы можете объединить все строки в одну.

Если вы также хотите удалить LF или CRLF в последней строке, выполните следующие действия в vi.

$ vi file
:set binary
:set noeol
:w!
:f          look for [noeol] on the status line
:q
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.