Какой смысл добавлять новую строку в конец файла?

Некоторые компиляторы (особенно C или C ++) дают вам предупреждения о:

No new line at end of file

Я думал, что это будет проблема только с C-программистами, но github отображает сообщение в представлении фиксации:

\ No newline at end of file

для файла PHP.

Я понимаю, что препроцессор, описанный в этом потоке , но что это касается PHP? Является ли это тегом include() или связано с темой \r\n vs \n?

В чем смысл новой строки в конце файла?

116 голосов | спросил Ps0ke 14 PM000000110000003231 2011, 23:29:32

6 ответов


131

Речь идет не о добавлении дополнительной строки в конце файла, а о том, чтобы не удалить новую строку, которая должна быть там.

A текстовый файл под UNIX состоит из серии строки , каждая из которых заканчивается символ новой строки (\n). Следовательно, файл, который не является пустым и не заканчивается символом новой строки, не является текстовым файлом.

Утилиты, которые должны работать с текстовыми файлами, могут плохо справляться с файлами, которые не заканчиваются новой строкой; Например, исторические утилиты Unix могут игнорировать текст после последней строки новой строки. Утилиты GNU имеют политику поведения прилично с нетекстовыми файлами, а также большинство других современных утилит, но вы все равно можете столкнуться с нечетным поведением с файлами, которые не имеют окончательной новой строки.

С GNU diff, если один из сравниваемых файлов заканчивается новой строкой, но не другой, обратите внимание на этот факт. Поскольку diff является ориентированным на линию, он не может указывать на это, сохраняя новую строку для одного из файлов, но не для других. Новые строки необходимы, чтобы указать, где каждая строка в файле diff начинается и заканчивается. Таким образом, diff использует этот специальный текст \ No newline at end of file, чтобы отличать файл, который не заканчивался в новой строке из файла, который сделал.

Кстати, в контексте C исходный файл аналогично состоит из ряда строк. Точнее, блок перевода рассматривается в реализации, определенной как ряд строк, каждый из которых должен заканчиваться символом новой строки ( n1256 §.5.1.1.1). В системах Unix отображение является простым. В DOS и Windows каждая последовательность CR LF (\r\n) сопоставляется с новой строкой (\n), что всегда происходит при чтении файла, открытого как текст на этих ОС). Есть несколько ОС, которые не имеют символа новой строки, но вместо этого имеют записи фиксированного или переменного размера; в этих системах отображение из файлов в источник C вводит \n в конце каждой записи. Хотя это не имеет прямого отношения к unix, это означает, что если вы скопируете исходный файл C, в котором отсутствует его окончательная новая строка, в систему с текстовыми файлами на основе записей, скопируйте их обратно, вы либо закончите с неполным последняя строка, усеченная при первоначальном преобразовании, или дополнительная новая строка, прикрепленная к ней во время обратного преобразования.

¹ Пример: вывод GNU-сортировки всегда заканчивается новой строкой. Поэтому, если в файле foo отсутствует его окончательная новая строка, вы обнаружите, что sort foo | wc -c сообщает еще один символ, чем cat foo | wc -c. Суб>

ответил Gilles 15 PM00000080000000131 2011, 20:10:01
30

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

Подумайте, что произойдет, если вы захотите обработать несколько файлов с помощью cat. Например, если вы хотите найти слово foo в начале строки по трем файлам:

cat file1 file2 file3 | grep -e '^foo'

Если первая строка в файле3 начинается с foo, но файл file2 не имеет окончательного \n после его последней строки, это событие не будет найдено grep, потому что последняя строка в файле2 и первая строка в файле3 будут видны grep как одна строка.

Итак, для консистенции и во избежание сюрпризов я стараюсь, чтобы мои файлы всегда заканчивались новой строкой.

ответил Sergio Acosta 18 PM000000110000002231 2011, 23:01:22
12

Есть два аспекта:

  1. Есть /были некоторые компиляторы C, которые не могут проанализировать последнюю строку, если она не заканчивается новой строкой. В стандарте C указано, что файл C должен заканчиваться новой строкой (C11, 5.1.1.2, 2.) и что последняя строка без новой строки дает неопределенное поведение (C11, J.2, 2-й элемент). Возможно, по историческим причинам, потому что какой-то поставщик такого компилятора был частью комитета, когда был написан первый стандарт. Таким образом, предупреждение GCC.

  2. Программы
  3. diff (например, используемые git diff, github и т. д.) показывают линейные различия между файлами. Обычно они печатают сообщение, когда только один файл заканчивается символом новой строки, потому что иначе вы не увидите эту разницу. Например, если единственное различие между двумя файлами - наличие последнего символа новой строки, без подсказки это будет выглядеть так, как оба файла были одинаковыми, когда diff и cmp возвращает неравный успех кода выхода, а контрольные суммы файлов (например, через md5sum) не совпадают.

ответил maxschlepzig 15 AM000000120000002631 2011, 00:29:26
7

В конце патча появляется \ No newline at end of file, который вы получаете из github (в diff , см. примечание в конце раздела« Унифицированный формат »).

Составители не заботятся о том, есть ли новая строка или нет в конце файла, но gitdiff /patch утилиты) должны учитывать их. Для этого есть много причин. Например, забыв добавить или удалить новую строку в конце файла, будет изменен ее хэш-массив (md5sum /sha1sum). Кроме того, файлы не всегда являются программами, а конечный \n может иметь значение.

Примечание . О предупреждении от компиляторов C, я думаю, они настаивают на окончательной новой строке для обратной совместимости. Очень старые компиляторы могут не принимать последнюю строку, если она не заканчивается \n (или другой системной последовательностью символов конца строки).

ответил Stéphane Gimenez 15 AM000000120000004031 2011, 00:03:40
2

Существует также точка сохранения истории различий. Если файл заканчивается без символа новой строки, то добавление чего-либо в конец файла будет просматриваться утилитами diff при изменении этой последней строки (потому что к нему добавляется \n).

Это может привести к нежелательным результатам с такими командами, как git blame и hg annotate.

ответил Hosam Aly 9 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowWed, 09 Sep 2015 21:25:00 +0300 2015, 21:25:00
1

POSIX, это набор стандартов, определенных IEEE для обеспечения совместимости между операционными системами.

Одним из них является определение «строки», представляющее собой последовательность из нуля или более символов без символа завершающей строки.

Итак, для того, чтобы эта последняя строка была признана фактической «строкой», она должна иметь завершающий новый символ строки.

Это важно, если вы полагаетесь на инструменты ОС, чтобы сказать количество строк или разделить /помочь проанализировать ваш файл. Учитывая, что PHP является языком скриптов, его вполне возможно, особенно в ранние дни или даже сейчас (я не знаю /постулирую), у него были зависимости от ОС.

В действительности, большинство операционных систем не полностью совместимы с POSIX, и люди не такие, как машины, или даже заботятся о завершении новых строк. Таким образом, для большинства вещей его smorgasbord всего, что он заботится об этом, предупреждает или просто идет, что последний бит текста - это действительно строка, поэтому просто включите его.

ответил user3379747 15 32017vEurope/Moscow11bEurope/MoscowWed, 15 Nov 2017 16:26:55 +0300 2017, 16:26:55

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132