Речь идет не о добавлении новой строки в конце файла, а об удалении новой строки, которая должна быть там.
Текстовый файл под 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
.