結論から言うと、Windows標準のfc.exeは、2つのファイルの差分をその場で確認するのに向いています。テキストは/l、バイナリは/bを明示し、自動処理では終了コード0、1、2を分けて扱ってください。PowerShellではfcが別コマンドのエイリアスなので、必ずfc.exeと書きます。
fc.exeは比較対象を変更しない読み取り型のコマンドですが、オプションの意味を誤ると「差分なし」「比較成功」「実行エラー」を取り違えます。また、ファイルが完全に同じかだけを知りたい場合は、画面へ大量の差分を出すよりSHA256ハッシュの比較が適することがあります。
目的別の選び方
| やりたいこと | 使う方法 | 理由 |
|---|---|---|
| 設定ファイルの変更行を見たい | fc /l /n | 行単位の差分と行番号を表示できる |
| 大文字小文字を無視したい | fc /l /c | 英字の大小を差分にしない |
| 空白量を無視したい | fc /l /w | 連続する空白・タブをまとめて扱う |
| 実行ファイルや画像を比較したい | fc /b | バイト単位と16進オフセットで比較する |
| ファイルが完全一致するかだけ知りたい | 終了コードまたはGet-FileHash | 大量差分を読む必要がない |
| 行の集合として増減を見たい | PowerShellのCompare-Object | 左右どちらにだけある行かを示せる |
| ソースコードをマージしたい | 版管理・差分ツール | fc.exeにはマージや構文理解がない |
基本構文と最初の比較
コマンドプロンプトを開き、次の形式で実行します。パスに空白がある場合は引用符が必須です。空白がないパスにも引用符を付けておくと、後でフォルダー名が変わっても壊れにくくなります。
fc [オプション] "1つ目のファイル" "2つ目のファイル"
たとえば、変更前後の設定ファイルを行番号付きで比較するなら次のとおりです。
fc /l /n "C:\work\before.ini" "C:\work\after.ini"
/lは行単位のテキスト比較を明示し、/nは差分行へ行番号を付けます。/nは結果を非表示にするオプションではありません。比較結果を画面に出さず終了コードだけ使う場合は、出力をnulへ送ります。
テキスト比較の主要オプション
| オプション | 動作 | 注意点 |
|---|---|---|
/l | ASCIIモードで行単位に比較 | 実行系拡張子でもテキストとして扱いたいときに明示 |
/n | 差分に行番号を表示 | ASCII比較で使う |
/c | 英字の大文字小文字を無視 | 厳密一致の判定には付けない |
/w | 連続空白・タブを1空白として扱い、行頭・行末空白も無視 | インデント差が重要なファイルには不向き |
/t | タブを空白へ変換しない | 既定ではタブを8文字ごとの空白として扱う |
/a | 各差分群の先頭行と末尾行だけ表示 | 文字コードをASCIIへ変換する指定ではない |
/u | Unicodeテキストとして比較 | 文字コードの自動判定・変換機能ではない |
/lb数値 | 内部行バッファを変更 | 既定100行。長い連続差分で中止する場合に調整 |
/数値 | 再同期とみなす連続一致行数を指定 | 既定は2行 |
大文字小文字と空白を無視する例
fc /l /n /c /w "C:\work\before.conf" "C:\work\after.conf"
この指定では、Serverとserverの違い、連続空白の数、行頭・行末の空白を差分として扱いません。見た目だけを比較したいときには便利ですが、Pythonのインデント、Makefileのタブ、固定長データ、署名対象ファイルなどでは意味を変える可能性があります。厳密な比較では/cと/wを外してください。
タブと空白を区別する例
fc /l /n /t "C:\work\before.txt" "C:\work\after.txt"
fc.exeは既定でタブを8文字ごとの空白として比較します。タブそのものを残して比較したい場合に/tを使います。ただし、文字コードや改行コードが異なると広い範囲が差分になることがあります。比較用のコピーを同じ文字コードと改行コードへそろえてから実行すると切り分けやすくなります。
バイナリ比較は/bを使う
実行ファイル、ライブラリ、画像、圧縮ファイルなどをバイト単位で比較する場合は/bを使います。.exe、.com、.sys、.obj、.lib、.binは既定でもバイナリ比較ですが、スクリプトや手順書では意図を明確にするため明示する方が安全です。
fc /b "C:\work\before.bin" "C:\work\after.bin"
差分は、先頭からの相対16進オフセットと、1つ目・2つ目のファイルの異なるバイト値で表示されます。1行には相対16進オフセット、1つ目のファイルのバイト値、2つ目のファイルのバイト値がこの順に並びます。/bは差分後に再同期を試みないため、途中へ1バイト追加されたようなファイルでは、その後も大量の差分が続くことがあります。
「最初の違いだけ表示する」とは限りません。巨大ファイルの同一性だけを判定したいなら、出力を読まず終了コードを見るか、後述のSHA256を使います。
終了コード0・1・2を正しく使う
| 終了コード | 意味 | 自動処理での扱い |
|---|---|---|
| 0 | ファイルは同一 | 一致として続行 |
| 1 | ファイルは異なる | 差分検出として分岐。実行エラーではない |
| 2 | 比較中にエラー | パス、権限、構文、ファイル状態を確認 |
バッチファイルのif errorlevel 数値は「その値以上」で真になります。そのため、2、1の降順で判定します。1から先に判定すると、終了コード2も「1以上」として差分扱いになり、比較エラーを見逃します。
@echo off
fc /b "C:\work\before.bin" "C:\work\after.bin" >nul
if errorlevel 2 (
echo 比較エラー
exit /b 2
) else if errorlevel 1 (
echo ファイルは異なります
exit /b 1
) else (
echo ファイルは同一です
exit /b 0
)
差分内容も保存したい場合は、既存の重要ファイルへ上書きしない名前を使います。比較日時を含む新しいログへ出力し、内容を確認してから保管・削除してください。fc.exeによる比較そのものは元ファイルを変更しないため、比較操作のロールバックは不要です。
PowerShellではfc.exeと書く
PowerShellのfcは通常、Format-Customのエイリアスです。コマンドプロンプトの記事を見てPowerShellへそのままfcと入力すると、期待するファイル比較になりません。実行ファイル名を明示します。
& "$env:SystemRoot\System32\fc.exe" /l /n "C:\work\before.txt" "C:\work\after.txt"
$LASTEXITCODE
$LASTEXITCODEでfc.exeの終了コードを確認できます。PowerShellの自動化では、0、1、2をswitchなどで明示的に分け、1を例外として投げるかどうかは処理目的に合わせて決めます。
Compare-ObjectとGet-FileHashの使い分け
行の増減を一覧にしたい場合
$before = Get-Content -LiteralPath "C:\work\before.txt"
$after = Get-Content -LiteralPath "C:\work\after.txt"
Compare-Object -ReferenceObject $before -DifferenceObject $after
Compare-Objectは、1つ目だけにある値を<=、2つ目だけにある値を=>で示します。ただし、既定の使い方は行の集合比較であり、一般的な差分ツールのように前後の文脈や位置を完全に再現するものではありません。重複行や順序が重要なら、結果の意味を確認して使います。
完全一致だけを確認したい場合
Get-FileHash -Algorithm SHA256 -LiteralPath "C:\work\before.bin","C:\work\after.bin"
2つのHashが同じなら、2ファイルの内容は同一です。既定もSHA256ですが、手順書ではアルゴリズムを明示すると読み違いを防げます。配布物の真正性を確かめる場合は、同じPC上の2ファイル同士ではなく、提供元が安全な経路で公開した既知のSHA256と照合します。ハッシュ一致だけで配布元の身元まで証明できるわけではありません。
実務で迷いやすい比較例
設定変更は厳密比較から始める
本番反映前の設定ファイルは、最初に空白や大文字小文字も含めて比較します。タブを空白へ置き換えたくない場合は/tを付けます。
fc /l /n /t "C:\config\baseline\app.conf" "C:\config\candidate\app.conf"
差分が大量で、原因が整形だけだと確認できた後に限り、二回目として/c /wを使います。最初から空白を無視すると、値の区切りやインデントに意味がある変更を見落とします。比較用コピーを使い、元の設定ファイルを文字コード変換や整形で上書きしないでください。
fc /l /n /c /w "C:\config\baseline\app.conf" "C:\config\candidate\app.conf"
複数ファイルは対応関係を先に確認する
fc.exeはファイル名に*や?のワイルドカードを使えます。ただし、比較対象の集合と対応する名前を確認せずに実行すると、意図した組み合わせとは限りません。最初に両フォルダーのファイル一覧を確認し、重要な比較はファイル名を明示して実行します。
fc /l "C:\config\baseline\*.ini" "C:\config\candidate\*.ini"
ワイルドカード結果に「ファイルがない」という差が含まれる場合は、内容差と欠落を別に記録します。fc.exeはフォルダー同期ツールではないため、比較結果を見て自動的にコピーや削除を行いません。欠落が意図したものかを所有者へ確認してから、別の承認済み手順で反映します。
差分レポートは新しいファイルへ出す
レビュー用に結果を残す場合は、既存ログと重ならない新しい名前を指定します。標準出力だけを保存する例は次のとおりです。
fc /l /n "C:\work\before.txt" "C:\work\after.txt" > "C:\work\fc-result-new.txt"
作成後はファイルを開き、比較対象名、差分、実行エラーが記録されているか確認します。終了コード2のときは、レポートが作られていても正常な差分結果とはみなしません。レポートには設定値や機密情報が含まれる可能性があるため、共有先と保管期限も元ファイルと同じ基準で管理します。
比較できない・結果がおかしい場合
| 症状 | 原因候補 | 確認方法 |
|---|---|---|
| PowerShellで意味不明な表示になる | fcがFormat-Customとして実行 | fc.exeまたはフルパスを使う |
| FC: cannot openと表示される | パス、引用符、権限、ファイル名 | 両ファイルを別々に開けるか確認する |
| ほぼ全行が差分になる | 文字コード、改行、タブ、挿入位置 | 比較用コピーの形式をそろえ、/tや/wを見直す |
| 長い連続差分で比較が中止される | 既定の行バッファ100行を超えた | /lb200など必要量へ増やす |
| 差分があるのに自動処理が成功扱い | 終了コード1を未判定 | 0、1、2を明示的に分ける |
| 異なるはずの空白が出ない | /wで空白差を無視 | /wを外し、必要なら/tを付ける |
| バイナリ差分が多すぎる | 挿入・圧縮・暗号化で後続バイトが変化 | 同一性だけならSHA256へ切り替える |
よくある質問
fcとcompは同じですか
別のコマンドです。fc.exeはテキストの行単位比較とバイナリ比較を切り替えられます。compは主にバイト単位でファイルまたはファイル集合を比較します。この記事のコマンドへcompのオプションを混ぜないでください。
/nは差分を非表示にしますか
いいえ。/nはASCII比較で行番号を表示します。表示を抑えて終了コードだけ使うなら、コマンドプロンプトで>nulへリダイレクトします。
UTF-8のファイルは/uで比較すればよいですか
/uは公式にはUnicodeテキスト比較の指定ですが、異なる文字コードを自動変換する機能ではありません。結果が不自然なら、元ファイルを変更せず比較用コピーを作り、同じ文字コードと改行コードへそろえてください。
fcでファイルが改変されることはありますか
fc.exeは比較対象を読み取り、差分を表示するため、元ファイルを書き換えません。ただし、結果を>で既存ファイルへ出すと、その出力先は上書きされます。新しいログ名を使ってください。
終了コード1はコマンドの失敗ですか
fc.exeでは「正常に比較し、相違を見つけた」という結果です。比較不能を示す終了コード2とは分けます。CIやバッチで差分を失敗扱いにするかは、業務ルールとして決めます。
まとめ
fc.exeは、テキスト比較なら行番号付きの /n、バイナリ比較なら /b を使い分けます。終了コード0は一致、1は相違、2は比較不能です。PowerShellでは fc が別名として解釈される場合があるため、Windows標準の比較コマンドを確実に呼ぶときは fc.exe と入力してください。
公式資料
差分の場所を読むならfc.exe、同一性だけなら終了コードまたはSHA256、構造化されたレビューやマージなら専用の差分・版管理ツール、と使い分けるのが確実です。

コメント