it-swarm-ru.tech

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

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

_No new line at end of file
_

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

_\ No newline at end of file
_

для файла PHP.

Я понимаю, что препроцессор объясняется в этот поток , но какое это имеет отношение к PHP? Это то же самое include() или это связано с темой _\r\n_ vs _\n_?

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

197
Philipp Stephan

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

текстовый файл в 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.

223
Gilles 'SO- stop being evil'

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

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

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

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

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

48
Sergio Acosta

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

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

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

17
maxschlepzig

\ No newline at end of file вы получаете от github появляется в конце патча (в diff format , см. примечание в конце "Unified Format" " раздел).

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

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

12
Stéphane Gimenez

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

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

6
Hosam Aly

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

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

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

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

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

4
user3379747