web-dev-qa-db-ja.com

ファイルの最後に新しい行を追加する意味は何ですか?

一部のコンパイラ(特にCまたはC++のコンパイラ)では、次の警告が表示されます。

_No new line at end of file
_

これはCプログラマーのみの問題だと思いましたが、githubはコミットビューにメッセージを表示します。

_\ No newline at end of file
_

PHPファイルの場合。

this thread で説明されているプリプロセッサのことは理解していますが、これはPHPと何が関係していますか?同じinclude()のことですか、それとも_\r\n_と_\n_のトピックに関連していますか?

ファイルの最後に改行を入れる意味は何ですか?

197
Philipp Stephan

ファイルの最後に余分な改行を追加することではなく、そこにあるはずの改行を削除しないことです。

テキストファイル は、UNIXでは、一連の で構成され、それぞれが 改行文字 で終わります(\n) 。したがって、空でなく、改行で終わらないファイルは、テキストファイルではありません。

テキストファイルを操作することになっているユーティリティは、改行で終わらないファイルにうまく対応しない場合があります。たとえば、歴史的なUnixユーティリティは、最後の改行の後のテキストを無視する可能性があります。 [〜#〜] gnu [〜#〜] ユーティリティには、非テキストファイルで適切に動作するというポリシーがあり、他のほとんどの最新のユーティリティでも同様の動作をしますが、最後の改行がありません¹。

GNU diffの場合、比較対象のファイルの一方が改行で終わり、もう一方が終わらない場合、その事実に注意してください。diffは行指向であるため、これを示すことはできません他のファイルではなく、ファイルの1つに改行を格納することにより、改行は各行の場所を示すために必要ですdiffファイル内開始と終了。したがって、diffはこの特別なテキスト\ No newline at end of fileを使用します改行で終わっていないファイルと終わっているファイルを区別します。

ちなみに、Cのコンテキストでは、ソースファイルも同様に一連の行で構成されています。より正確には、翻訳単位は、実装で定義された一連の行として表示され、各行は改行文字( n1256 §5.1.1.1)で終了する必要があります。 UNIXシステムでは、マッピングは簡単です。 DOSおよびWindowsでは、各CR LFシーケンス(\r\n)は改行(\n)にマップされます。これは、テキストとして開いたファイルを読み取るときに常に行われることです。これらのOS)には、改行文字がなく、代わりに固定サイズまたは可変サイズのレコードがあるOSがいくつかあります。これらのシステムでは、ファイルからCソースへのマッピングで\nが導入されます各レコードの終わりです。これはunixには直接関係ありませんが、最終的な改行が欠落しているCソースファイルを、レコードベースのテキストファイルを持つシステムにコピーしてからコピーすると、元に戻ります。最初の変換で不完全な最後の行が切り捨てられるか、逆変換中に余分な改行が追加されます。

¹ 例:GNU sortの出力は常に改行で終了します。そのため、ファイルfooに最後の改行がない場合、sort foo | wc -cが1つを報告することがわかりますcat foo | wc -cより多くの文字。

必ずしも理由ではありませんが、ファイルが改行で終わっていないという実際的な結果:

catを使用して複数のファイルを処理したい場合はどうなるか考えてください。たとえば、3つのファイルの行頭にWord fooを見つけたい場合は、次のようにします。

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

File3の最初の行がfooで始まるが、file2の最後の行の後に最後の\nがない場合、この出現はgrepによって検出されません。file2の最後の行と最初の行がfile3の行は、grepによって1行として表示されます。

したがって、一貫性を保つため、また驚きを避けるために、ファイルは常に新しい行で終わるようにしています。

48
Sergio Acosta

2つの側面があります。

  1. 改行で終わっていない場合、最後の行を解析できないCコンパイラがいくつかあります。 C標準では、Cファイルは改行(C11、5.1.1.2、2)で終わる必要があり、改行のない最後の行は未定義の動作(C11、J.2、2番目の項目)になることを指定しています。おそらく歴史的な理由によると思われます。そのようなコンパイラの一部のベンダーは、最初の標準が作成されたときに委員会に参加していたためです。したがって、GCCによる警告。

  2. diffプログラム(git diff、githubなどで使用される)は、ファイル間の行ごとの違いを表示します。通常、1つのファイルのみが改行で終了するとメッセージが出力されます。それ以外の場合、この違いはわかりません。たとえば、2つのファイルの唯一の違いが最後の改行文字の存在であり、ヒントがない場合、diffcmpが終了を返すと、両方のファイルが同じであるように見えますコードの不成功とファイルのチェックサム(例:md5sum経由)が一致しません。

17
maxschlepzig

githubから取得する\ No newline at end of fileは、パッチの最後に表示されます( diff format で、次のURLのメモを参照してください) 「統一フォーマット」セクションの終わり)。

コンパイラーはファイルの最後に改行があるかどうかを気にしませんが、git(およびdiff/patchユーティリティ)はそれらを考慮に入れる必要があります。それには多くの理由があります。たとえば、ファイルの最後に改行を追加または削除し忘れると、ハッシュサムが変更されます(md5sum/sha1sum)。また、ファイルは常にプログラムであるとは限らず、最後の\nは多少の違いをもたらす可能性があります。

:Cコンパイラからの警告については、下位互換性のために最終改行を要求していると思います。非常に古いコンパイラは、\n(または他のシステム依存の行末文字シーケンス)で終わっていない場合、最後の行を受け入れない可能性があります。

12

また、差分の履歴を保持するという点もあります。ファイルが改行文字なしで終了する場合、ファイルの最後に何かを追加すると、diffユーティリティによってその最後の行が変更されたと見なされます(\nが追加されているため)。

これは、git blamehg annotateなどのコマンドで望ましくない結果を引き起こす可能性があります。

6
Hosam Aly

POSIX、これはオペレーティングシステム間の互換性を維持するためにIEEEによって指定された標準のセットです。

その1つは、ゼロ個以上の非文字のシーケンスと終端の改行文字である「行」の定義です。

したがって、その最後の行が実際の「行」として認識されるようにするには、改行文字で終了する必要があります。

これは、行数や分割/ファイルの解析をOSツールに依存している場合に重要です。与えられたPHPはスクリプト言語であり、特に初期または今でも完全に可能です(私は知らない/想定していない)そのようなOS依存関係がありました。

実際には、ほとんどのオペレーティングシステムはPOSIXに完全に準拠しておらず、人間はそのようなマシンではなく、新しいラインの終了を気にしていません。したがって、ほとんどの場合、それを気にかけたり、警告したり、テキストの最後の部分だけを行ったりすることのすべてが実際には行なので、それを含めてください。

4
user3379747