Windows Powershellで2つのテキストファイルを比較するにはどうすればよいですか?


96

2つのテキストファイルがあり、Windows Powershellを使用してそれらの違いを見つけたいです。Unix diffツールに似たものはありますか?または、私が考えていない別の方法がありますか?

私は比較オブジェクトを試しましたが、この不可解な出力を取得します:

PS C:\> compare-object one.txt two.txt

InputObject                                                 SideIndicator
-----------                                                 -------------
two.txt                                                     =>
one.txt                                                     <=

回答:


101

自分で考え出した。Powershellはテキストではなく.netオブジェクトで動作するため、get-contentを使用してテキストファイルのコンテンツを公開する必要があります。したがって、質問で私がやろうとしていたことを実行するには、次を使用します:

compare-object (get-content one.txt) (get-content two.txt)

1
並べ替えられていない数字の配列と、並べ替えた後の同じ数字の配列という2つのファイルを比較しようとしたとき、私は非常に驚きました。ファイルが大きく異なるにもかかわらず、出力はありません。どうやら、compare-objectは順序を考慮していません。
cgmb

1
@cgmb- -SyncWindow 0それを修正するために使用できますが、それが最近導入されたのかどうかはわかりませんが。ただし、特に賢くはありません。
ジェームズラスキン

32

より簡単な方法は、次のように書くことです:

diff (cat file1) (cat file2)

16
Diffとcatは、PowerShellのCompare-ObjectとGet-Contentの単なるエイリアスです。同じことです。
ショーンメルトン

4
これは受け入れられた答えと同じですが、私はこの構文をもっと使うのが好きです
エライジャW.

diffここの他の回答が指摘しているように、* nixのようにはまったく動作しないことに注意してください。そして、cat誤った出力を取得する代わりに、より複雑な式を使用した場合、* nixから来た場合、PowerShellでこれを行わないようにするために、他の人と一緒に推奨事項に参加します。
Nickolay

29

または、DOS fcコマンドを次のように使用できます(これにより、両方のファイルの出力が表示されるため、違いをスキャンする必要があります)。

fc.exe filea.txt fileb.txt > diff.txt

fcはFormat-Customコマンドレットのエイリアスなので、必ずコマンドとしてを入力してくださいfc.exe。多くのDOSユーティリティはUTF-8エンコーディングを処理しないことに注意してください。

CMDプロセスを生成して、その中で実行することもできますfc

start cmd "/c  ""fc filea.txt fileb.txt >diff.txt"""

これは、引用符で囲まれたパラメーターを使用して 'cmd'プログラムでプロセスを開始するようにPowerShellに指示します。引用符で囲まれているのは、コマンドを実行して終了する '/ c' cmdオプションです。プロセスでcmdによって実行される実際のコマンドはfc filea.txt fileb.txt、出力をファイルにリダイレクトしていますdiff.txt

fc.exePowerShell内からDOSを使用できます。


2
DOSを引き出すための+1 ^ _ ^
ジェフブリッジマン

1
「fc」は機能していなかったので、Format-Customと区別するために「fc.exe」と指定する必要があることに気付きませんでした。まさに私が探していたもの。ありがとう。
Xonatron

私は完全な哲学者かもしれませんが、これは私にとってはるかに使いやすいようです。それは私の問題を非常にうまく解決しました。
AJ。

唯一の問題は、ユニコードが嫌いです。
iCodeSometime

7

* nixのdiffはシェルの一部ではなく、別個のアプリケーションです。

PowerShellでdiff.exeを使用できない理由はありますか?

UnxUtilsパッケージ(http://unxutils.sourceforge.net/)からバージョンをダウンロードできます。


10
PowerShellが含まれているため、ダウンロードしてインストールする必要はありません。
Bratch

git diff既にインストールしているため、最終的にを使用しました。期待していた出力fc.exeCompare-Object生成しませんでした。
ラジエル

4

compare-object(別名diffエイリアス)は、unix diffのように動作すると予想される場合は哀れです。diff(gc file1)(gc file2)を試しましたが、行が長すぎると実際のdiffを見ることができず、さらに重要なことには、diffがどの行番号にあるのかわかりません。

-passthruを追加しようとすると、違いがわかるようになりましたが、違いのあるファイルが失われ、行番号が表示されません。

私のアドバイスは、PowerShellを使用してファイルの違いを見つけないでください。他の誰かが指摘したように、fcは動作し、compare-objectよりも少し良く動作し、Mikeageが言及したUnixエミュレーターのような実際のツールをダウンロードして使用することはさらに良いです。


また-SyncWindow、デフォルトでmaxintのように、セットの比較(つまり、順序の無視)を行うように見えます。それを0に設定してdiffも、どちらのようにも機能しません...そして、パイプ(... | select-object ...)を入力として渡したとき、それはナンセンスを出力したので、私はあきらめました。
Nickolay

3

他の人が指摘したように、unix-y diff出力を期待している場合、powershell diffエイリアスを使用すると、あなたは大変なことになります。一つには、ファイルを実際に読み込む際に(gc / get-contentを使用して)手を握らなければなりません。別の場合、差異インジケータは右側にあり、コンテンツからはほど遠い-それは読みやすさの悪夢です。

正気な出力を探している人のためのソリューションは

  1. 実際の差分を取得する(例:GnuWin32から)
  2. %USERPROFILE%\ Documents \ WindowsPowerShell \ Microsoft.PowerShell_profile.ps1を編集します
  3. 行を追加

    remove-item alias:diff -force

Powershellはこの特定の組み込みエイリアスについて非常に貴重であるため、-force引数が必要です。GnuWin32がインストールされていることに興味がある人は、PowerShellプロファイルに次のものも含めます。

remove-item alias:rm
remove-item alias:mv
remove-item alias:cp

主に、Powershellは一緒に実行されて入力される引数を理解しないため、たとえば「rm -Force -Recurse」は「rm -rf」よりもはるかに手間がかかります。

Powershellにはいくつかの便利な機能がありますが、私が試してはいけないことがいくつかあります。




1

fc.exe* nix diffのように動作するように設計されているため、テキスト比較に適しています。つまり、行を順次比較し、実際の違いを示し、再同期を試みます(異なるセクションの長さが異なる場合)。また、いくつかの便利な制御オプション(テキスト/バイナリ、大文字と小文字の区別、行番号、再同期の長さ、バッファーサイズの不一致)があり、終了ステータス(-1不正な構文、0ファイルが同じ、1ファイルが異なる、2ファイルが欠落)を提供します。(非常に)古いDOSユーティリティであるため、いくつかの制限があります。最も顕著なのは、Unicodeで自動的に動作せず、ASCII文字の0 MSBを行終端文字として扱うため、ファイルは1文字行のシーケンスになります(@kennycoc:/ Uオプションを使用して、両方のファイルがUnicode、WinXP以降を指定する)また、128文字(128バイトASCII、

compare-objectは、2つのオブジェクトがメンバーごとに同一であるかどうかを判断するように設計されています。オブジェクトがコレクションの場合、それらはSETS(help compare-objectを参照)、つまり重複のないUNORDEREDコレクションとして扱われます。2つのセットは、順序または複製に関係なく同じメンバーアイテムを持っている場合、等しくなります。これにより、テキストファイルの違いを比較する際の有用性が大幅に制限されます。まず、デフォルトの動作では、オブジェクト全体(ファイル=文字列の配列)がチェックされるまで違いが収集されるため、違いの位置に関する情報が失われ、どの違いがペアになっているかがわかりにくくなります(SETの行番号の概念はありません)文字列の)。-synchwindow 0を使用すると、差異が発生すると出力されますが、1つのファイルに余分な行がある場合、ファイルが同じ場合でも後続の行比較が失敗する可能性があります(補償があるまで)他のファイルの余分な行により、一致する行が再配置されます)。ただし、powershellは非常に汎用性が高く、この機能を利用することで、ファイルの内容にある程度の制限がありますが、かなり複雑になりますが、便利なファイル比較を行うことができます。テキストファイルを長い(127文字を超える)行で比較する必要があり、行がほとんど一致する場合:

diff (gc file1 | % -begin { $ln1=0 } -process { '{0,6}<<:{1}' -f ++$ln1,$_ }) (gc file2 | % -begin { $ln2=0 } -process { '{0,6}>>:{1}' -f ++$ln2,$_ }) -property { $_.substring(9) } -passthru | sort | out-string -width xx

ここで、xxは最も長い行の長さ+ 9

説明

  • (gc file | % -begin { $ln=0 } -process { '{0,6}<<:{1}' -f ++$ln,$_ }) ファイルの内容を取得し、行番号とファイルインジケータ(<<または>>)を各行に追加してから(書式文字列演算子を使用)、diffに渡します。
  • -property { $_.substring(9) }最初の9文字(行番号とファイルインジケータ)を無視して、オブジェクト(文字列)の各ペアを比較するようにdiffに指示します。これは、プロパティの名前の代わりに計算されたプロパティ(スクリプトブロックの値)を指定する機能を利用します。
  • -passthru diffは、異なる比較オブジェクト(出力しない)の代わりに、異なる入力オブジェクト(行番号とファイルインジケーターを含む)を出力します。
  • sort-object次に、すべての行をシーケンスに戻します。
    out-stringは、切り捨てを避けるのに十分な幅を指定することにより、出力のデフォルトの切り捨てを停止して(Marc Towersapが指摘した)画面幅に合わせます。通常、この出力はファイルに書き込まれ、スクロールエディター(メモ帳など)を使用して表示されます。

注意

行番号の形式{0,6}は、右詰めでスペースが埋め込まれた6文字の行番号(ソート用)を提供します。ファイルの行数が999,999を超える場合は、フォーマットを変更して幅を広げます。これには、$_.substringパラメーター(行番号の幅よりも3大きい)およびストリング外xx値(最大行長+ $_.substringパラメーター)の変更も必要です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.