web-dev-qa-db-ja.com

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

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

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

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

InputObject                                                 SideIndicator
-----------                                                 -------------
two.txt                                                     =>
one.txt                                                     <=
104
Brian Willis

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

compare-object (get-content one.txt) (get-content two.txt)
110
Brian Willis

それを行う簡単な方法は、次のように書くことです。

diff (cat file1) (cat file2)
34
Alex Y.

または、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にリダイレクトします。

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

32
phord350

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

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

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

7
Mikeage

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

-passthruを追加しようとすると、違いがわかりますが、違いがどのファイルにあるかがわかりません。それでも、行番号がわかりません。

ファイルの違いを見つけるためにpowershellを使用しないでください。他の誰かが指摘したように、fcは機能し、compare-objectより少し優れており、Mikeageが述べたunixエミュレーターのような実際のツールをダウンロードして使用することはさらに優れています。

4
Marc Towersap

他の人が指摘しているように、unix-yの差分出力を期待している場合は、powershell diffエイリアスを使用するとハードダウンできます。 1つには、実際にファイルを読み取るときに(gc/get-contentを使用して)手に持っている必要があります。もう1つは、違いのインジケーターがコンテンツから離れた右側にあります。これは読みやすさの悪夢です。

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

  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にはいくつかの素晴らしい機能がありますが、私のためにやろうとしてはいけないことがいくつかあります。

3
daf

WinMerge は、別の優れたGUIベースの差分ツールです。

2
Andy White

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

compare-objectは、2つのオブジェクトがメンバーごとに同一であるかどうかを判別するように設計されています。オブジェクトがコレクションである場合、それらはSETS(ヘルプcompare-objectを参照)、つまり重複のないUNORDEREDコレクションとして扱われます。順序や重複に関係なく、同じメンバーアイテムがある場合、2セットは等しくなります。これにより、テキストファイルの違いを比較する際の有用性が大幅に制限されます。まず、デフォルトの動作では、オブジェクト全体(ファイル=文字列の配列)がチェックされるまで差異が収集されるため、差異の位置に関する情報が失われ、ペアになっている差異が不明瞭になります(SETの行番号の概念はありません)。文字列の)。 -synchwindow 0を使用すると、差異が発生すると出力されますが、再同期の試行が停止されるため、1つのファイルに余分な行がある場合、他のファイルが同一であっても後続の行の比較が失敗する可能性があります(補正があるまで)他のファイルの余分な行により、一致する行が再調整されます)。ただし、powershellは非常に用途が広く、かなりの複雑さを犠牲にしてファイルの内容にいくつかの制限がありますが、この機能を利用することにより、便利なファイル比較を行うことができます。長い(> 127文字)行を含むテキストファイルを比較する必要があり、行が1:1にほぼ一致する場合(ファイル間の行の一部の変更はあるが、キーフィールドを持つデータベースレコードのテキストリストなど、ファイル内の重複がない)次に、それがどのファイルにあるか、そのファイル内での位置を示す情報を各行に追加し、比較時に追加された情報を無視します(ただし、出力には含めます)。次のように* nix diffのような出力を取得できます(エイリアスの省略形を使用) ):

_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_を指定すると、比較対象の異なるオブジェクト(行番号とファイルインジケーターを含む)ではなく、異なる入力オブジェクト(行番号とファイルインジケーターを含む)が出力されます。
  • _sort-object_は、すべての行をシーケンスに戻します。
    out-stringは、切り捨てを回避するのに十分な幅を指定することにより、(Marc Towersapが指摘するように)画面幅に合わせて出力のデフォルトの切り捨てを停止します。通常、この出力はファイルに入れられ、スクロールエディター(メモ帳など)を使用して表示されます。

注意

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

1
codemaster bob

Windiff もあり、これはGUI差分インターフェースを提供します(GUIベースのCVS/SVNプログラムでの使用に最適)

1
saschabeaumont