Não se trata de adicionar uma nova linha extra no final de um arquivo, mas de não remover a nova linha que deveria estar lá.
Um arquivo de texto , em unix, consiste em uma série de linhas , cada uma das quais termina com um caractere de nova linha ( \n
). Um arquivo que não está vazio e não termina com uma nova linha não é, portanto, um arquivo de texto.
Utilitários que devem operar em arquivos de texto podem não lidar bem com arquivos que não terminam com uma nova linha; utilitários históricos do Unix podem ignorar o texto após a última nova linha, por exemplo. Os utilitários do GNU têm uma política de se comportar de maneira decente com arquivos que não são de texto, assim como a maioria dos outros utilitários modernos, mas você ainda pode encontrar um comportamento estranho com arquivos que estão faltando uma nova linha final¹.
Com o GNU diff, se um dos arquivos que estão sendo comparados termina com uma nova linha, mas não com o outro, é necessário observar esse fato. Como diff é orientado a linhas, ele não pode indicar isso armazenando uma nova linha para um dos arquivos, mas não para os outros - as novas linhas são necessárias para indicar onde cada linha no arquivo diff é iniciada e termina. Então o diff usa esse texto especial \ No newline at end of file
para diferenciar um arquivo que não termina em uma nova linha de um arquivo que fez.
A propósito, em um contexto C, um arquivo de origem é composto de uma série de linhas. Mais precisamente, uma unidade de tradução é visualizada em uma implementação definida como uma série de linhas, cada uma das quais deve terminar com um caractere de nova linha ( n1256 §5.1.1.1). Em sistemas unix, o mapeamento é direto. No DOS e no Windows, cada seqüência CR LF ( \r\n
) é mapeada para uma nova linha ( \n
; isso é o que sempre acontece ao ler um arquivo aberto como texto nesses sistemas operacionais). Existem alguns sistemas operacionais que não possuem um caractere de nova linha, mas possuem registros de tamanho fixo ou variável; nesses sistemas, o mapeamento dos arquivos para a origem C introduz um \n
no final de cada registro. Embora isso não seja diretamente relevante para o unix, isso significa que, se você copiar um arquivo de origem C sem a nova linha final para um sistema com arquivos de texto baseados em registros, copie-o de volta, ou você acabará com o arquivo incompleto. última linha truncada na conversão inicial ou uma nova linha extra inserida nela durante a conversão inversa.
Exemplo: a saída da classificação GNU sempre termina com uma nova linha. Portanto, se o arquivo foo
não tiver sua nova linha final, você verá que sort foo | wc -c
informa mais um caractere do que cat foo | wc -c
.