Windows Powershellで2つのフォルダーを比較するにはどうすればよいですか?


11

Windows Powershellを使用して、2つのフォルダー構造のコンテンツの違いを見つけようとしています。次の方法を使用してファイル名が同じであることを確認しましたが、この方法ではファイルの内容が同じかどうかはわかりません。

$firstFolder = Get-ChildItem -Recurse folder1
$secondFolder = Get-ChildItem -Recurse folder2
Compare-Object -ReferenceObject $firstFolder -DifferenceObject $secondFolder

このServerFaultの質問で説明されている手法は、単一のファイルを比較するために機能しますが、これらのフォルダーにはさまざまな深さの何百ものファイルが含まれています。

解決策は、必ずしもファイル内の具体的な違いを教えてくれる必要はありません-それだけです。日付などのメタデータの違いには興味がありません。

回答:


15

比較をループにラップする場合は、次のアプローチを取ります。

$folder1 = "C:\Users\jscott"
$folder2 = "C:\Users\public"

# Get all files under $folder1, filter out directories
$firstFolder = Get-ChildItem -Recurse $folder1 | Where-Object { -not $_.PsIsContainer }

$firstFolder | ForEach-Object {

    # Check if the file, from $folder1, exists with the same path under $folder2
    If ( Test-Path ( $_.FullName.Replace($folder1, $folder2) ) ) {

        # Compare the contents of the two files...
        If ( Compare-Object (Get-Content $_.FullName) (Get-Content $_.FullName.Replace($folder1, $folder2) ) ) {

            # List the paths of the files containing diffs
            $_.FullName
            $_.FullName.Replace($folder1, $folder2)

        }
    }   
}

これは、存在しないファイルを無視することに注意してください両方で $folder1とを$folder2


5

私はjscottの答えを拡張して、そのタイプの機能に興味がある人のために、一方には存在するがもう一方には存在しないファイルを出力するように拡張しました。あまり大きな違いのない巨大なフォルダーを考えるとわかりにくいので、進捗状況も表示されることに注意してください。スクリプトが私に掛けられているように見えました。そのためのPowerShellコードを次に示します。

$folder1 = "C:\Folder1"
$folder2 = "C:\Folder2"

# Get all files under $folder1, filter out directories
$firstFolder = Get-ChildItem -Recurse $folder1 | Where-Object { -not $_.PsIsContainer }

$failedCount = 0
$i = 0
$totalCount = $firstFolder.Count
$firstFolder | ForEach-Object {
    $i = $i + 1
    Write-Progress -Activity "Searching Files" -status "Searching File  $i of     $totalCount" -percentComplete ($i / $firstFolder.Count * 100)
    # Check if the file, from $folder1, exists with the same path under $folder2
    If ( Test-Path ( $_.FullName.Replace($folder1, $folder2) ) ) {
        # Compare the contents of the two files...
        If ( Compare-Object (Get-Content $_.FullName) (Get-Content $_.FullName.Replace($folder1, $folder2) ) ) {
            # List the paths of the files containing diffs
            $fileSuffix = $_.FullName.TrimStart($folder1)
            $failedCount = $failedCount + 1
            Write-Host "$fileSuffix is on each server, but does not match"
        }
    }
    else
    {
        $fileSuffix = $_.FullName.TrimStart($folder1)
        $failedCount = $failedCount + 1
        Write-Host "$fileSuffix is only in folder 1"
    }
}

$secondFolder = Get-ChildItem -Recurse $folder2 | Where-Object { -not $_.PsIsContainer }

$i = 0
$totalCount = $secondFolder.Count
$secondFolder | ForEach-Object {
    $i = $i + 1
    Write-Progress -Activity "Searching for files only on second folder" -status "Searching File  $i of $totalCount" -percentComplete ($i / $secondFolder.Count * 100)
    # Check if the file, from $folder2, exists with the same path under $folder1
    If (!(Test-Path($_.FullName.Replace($folder2, $folder1))))
    {
        $fileSuffix = $_.FullName.TrimStart($folder2)
        $failedCount = $failedCount + 1
        Write-Host "$fileSuffix is only in folder 2"
    }
}

Compare-Objectを呼び出すときに、ファイルの実際の内容を抽出するのはなぜですか?それがCompare-Objectの機能です。technet.microsoft.com/en-us/library/...
キャスパーレオン・ニールセン

1

既にこれに答えているリンクされた質問からの正しい答えの周りにループをラップし、同じ名前を持つすべてのファイルを比較するディレクトリツリーを歩きます。

/編集:それが実際にあなたの質問である場合、それはあなたが通常の貢献者であると思われるSOにとってより適切です。あなたはプログラミングの質問をしています。sysadminタイプの目的でそれを行っていることを理解しています。その場合、WinDiffなどの専用ツールを使用するように指示します。


2
OK、このサイトは「Give me the codez」タイプの質問には適していません。Powershellでループを行う方法の学習を開始する必要がある場合は、本を購入するか、オンラインチュートリアルを見つけてください。沢山あります。
mfinni

2
ベッドの反対側で目が覚めたと思う。私は通常のPowershellユーザーではありません。私の質問では、現在試みている手法と、問題に役立つ追加情報がある質問へのリンクの両方を示しました。私の問題である2つのテクニックを組み合わせる方法がわかりません。また、この質問をした理由もわかりません。また、Google検索を使用して答えることができなかった質問です。役に立たない場合は、回答を削除することを検討してください。
デビッドスミス

2
@BigDave 文字通り最初の結果のためにPowerShell loop through filesGoogleで。さあ、今度は少し努力してください。
voretaq7

2
@ voretaq7皆さんは私をPowerShellユーザーとして誤解していると思います。私はそのグーグル検索をして、そのテクニックを試みましたが、成功しませんでした。上記の質問のどこにいるかを説明しようとしました。リンクする質問は、単一のファイルセットで機能します。名前と名前を比較する必要がある2つのセットがあります。私は本当にここで怠beになろうとはしていません。ループする方法を知っており、比較する方法を知っています。ループし、2つのセットを比較するにはどうすればよいですか?
デビッドスミス

1
PSでこれを行うことは、素晴らしい小さなプロジェクトだと思います。ただし、WinMerge(これはWinDiffであると思いますが、私は愚かです)は、これを頻繁に行う場合には本当に素晴らしいツールです。それは文字通り仕事のために構築されています。試してみてください、ダウンロードは無料です。ほとんどの種類のファイルに分解機能があり、空白の処理方法のオプションを含む、強調表示に優れた機能を発揮します。
mfinni

0

これを行う:

compare (Get-ChildItem D:\MyFolder\NewFolder) (Get-ChildItem \\RemoteServer\MyFolder\NewFolder)

そしてさらに再帰的に:

compare (Get-ChildItem -r D:\MyFolder\NewFolder) (Get-ChildItem -r \\RemoteServer\MyFolder\NewFolder)

忘れることさえ難しいです:)

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