Alguns compiladores (especialmente os C ou C ++) emitem avisos sobre:
No new line at end of file
Eu pensei que isso seria um problema apenas de programadores C, mas o github exibe uma mensagem na exibição de confirmação:
\ No newline at end of file
para um arquivo PHP.
Eu entendo a coisa do pré-processador explicada neste tópico , mas o que isso tem a ver com PHP? É a mesma include()
coisa ou está relacionada ao tópico \r\n
vs \n
?
Qual é o sentido de ter uma nova linha no final de um arquivo?
cat
o arquivo, o próximo prompt será anexado à "linha" final se não terminar com uma nova linha.Respostas:
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 , no 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.Os utilitários que devem operar com arquivos de texto podem não funcionar bem com arquivos que não terminam com uma nova linha; utilitários Unix históricos podem ignorar o texto após a última nova linha, por exemplo. Os utilitários GNU têm uma política de comportamento 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 não possuem uma nova linha final¹.
Com o GNU diff, se um dos arquivos comparados termina com uma nova linha, mas não com o outro, é preciso observar esse fato. Como o diff é orientado a linhas, não é possível 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 finalizada. O diff usa esse texto especial
\ No newline at end of file
para diferenciar um arquivo que não terminou em uma nova linha de um arquivo que terminou.A propósito, em um contexto C, um arquivo de origem também consiste em uma série de linhas. Mais precisamente, uma unidade de tradução é vista 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 sequência CR LF (
\r\n
) é mapeada para uma nova linha (\n
; é o que sempre acontece ao ler um arquivo aberto como texto nesses sistemas operacionais). Existem alguns sistemas operacionais por aí que não têm um caractere de nova linha, mas possuem registros de tamanho fixo ou variável; nesses sistemas, o mapeamento de arquivos para a origem C introduz um\n
no final de cada registro. Embora isso não seja diretamente relevante para o unix, significa que, se você copiar um arquivo de origem C que está perdendo sua nova linha final em um sistema com arquivos de texto com base em registros e copiá-lo novamente, você terminará com o arquivo incompleto a última linha truncada na conversão inicial ou uma nova linha extra pregada nela durante a conversão reversa.¹ Exemplo: a saída da classificação GNU sempre termina com uma nova linha. Portanto, se o arquivo
foo
estiver com sua nova linha final em falta, você encontrarásort foo | wc -c
um relatório a mais de um caracterecat foo | wc -c
.fonte
Não necessariamente o motivo, mas uma consequência prática de arquivos que não terminam com uma nova linha:
Considere o que aconteceria se você quisesse processar vários arquivos usando
cat
. Por exemplo, se você deseja encontrar a palavrafoo
no início da linha em três arquivos:Se a primeira linha do arquivo3 começar com
foo
, mas o arquivo2 não tiver uma final\n
após a última linha, essa ocorrência não seria encontrada pelo grep, porque a última linha do arquivo2 e a primeira linha do arquivo3 seriam vistas pelo grep como uma única linha.Portanto, por consistência e para evitar surpresas, tento manter meus arquivos sempre terminando com uma nova linha.
fonte
'\n'
na operação de gato ...\n
espaço em branco nas extremidades; portanto, para manter as coisas consistentes, eu sempre coloco\n _____
nas duas extremidades das minhas strings". Bem, não, a coisa certa a fazer é cortar as cordas e concatená-las adequadamente.Existem dois aspectos:
Existem / existem alguns compiladores C que não podem analisar a última linha se ela não terminar com uma nova linha. O padrão C especifica que um arquivo C deve terminar com uma nova linha (C11, 5.1.1.2, 2.) e que uma última linha sem uma nova linha produz comportamento indefinido (C11, J.2, 2º item). Talvez por razões históricas, porque algum fornecedor desse compilador fazia parte do comitê quando o primeiro padrão foi escrito. Assim, o aviso do GCC.
diff
programas (como usado pelogit diff
github etc.) mostram diferenças linha por linha entre os arquivos. Eles geralmente imprimem uma mensagem quando apenas um arquivo termina com uma nova linha, pois senão você não veria essa diferença. Por exemplo, se a única diferença entre dois arquivos é a presença do último caractere de nova linha, sem a dica, pareceria que os dois arquivos eram iguais, quandodiff
ecmp
retornam um sucesso desigual no código de saída e as somas de verificação dos arquivos (por exemplo, viamd5sum
) não correspondem.fonte
diff
é esperado que imprima diferenças, se houver alguma. E se um arquivo tem uma nova linha como último caractere enquanto o outro não, então essa diferença deve ser notada de alguma forma na saída.\n
) para começar; ele pode simplesmente mostrar "novas linhas".O que
\ No newline at end of file
você obtém do github aparece no final de um patch (emdiff
formato , veja a nota no final da seção "Formato unificado").Os compiladores não se importam se há uma nova linha ou não no final de um arquivo, mas
git
(e osdiff
/patch
utilitários) precisam levar isso em consideração. Existem muitas razões para isso. Por exemplo, esquecer de adicionar ou remover uma nova linha no final de um arquivo alteraria seu hashsum (md5sum
/sha1sum
). Além disso, os arquivos nem sempre são programas, e uma final\n
pode fazer alguma diferença.Nota : Sobre o aviso dos compiladores C, acho que eles insistem em uma nova linha final para fins de compatibilidade com versões anteriores. Compiladores muito antigos podem não aceitar a última linha se não terminar com
\n
(ou outra sequência de caracteres de final de linha dependente do sistema).fonte
Há também o ponto de manter a história do diff. Se um arquivo terminar sem um caractere de nova linha, adicionar qualquer coisa ao final do arquivo será visualizado pelos utilitários diff como alterando a última linha (porque
\n
está sendo adicionada a ele).Isso pode causar resultados indesejados com comandos como
git blame
ehg annotate
.fonte
-w
opção para ignorar as alterações de espaço em branco ao gerar dados para humanos.POSIX, este é um conjunto de padrões especificados pelo IEEE para manter a compatibilidade entre sistemas operacionais.
Uma delas é a definição de uma "linha" como sendo uma sequência de zero ou mais caracteres não, além de um caractere de nova linha final.
Portanto, para que a última linha seja reconhecida como uma "linha" real, ela deve ter um caractere de nova linha final.
Isso é importante se você depende das ferramentas do SO para dizer a contagem de linhas ou dividir / ajudar a analisar seu arquivo. Dado que o PHP é uma linguagem de script, é inteiramente possível, especialmente nos seus primeiros dias ou até agora (não faço idéia / postulando) que tinha dependências do SO como essa.
Na realidade, a maioria dos sistemas operacionais não é totalmente compatível com POSIX e os humanos não são tão parecidos com máquinas ou se preocupam em terminar novas linhas. Portanto, para a maioria das coisas, é uma mistura de tudo, quer se preocupe com isso, avisar ou apenas passar o último pedaço de texto é realmente uma linha, então inclua-o.
fonte