Wie unterscheide ich zwei Ordner in Windows Powershell?


11

Ich versuche mit Windows Powershell Unterschiede im Inhalt von zwei Ordnerstrukturen zu finden. Ich habe die folgende Methode verwendet, um sicherzustellen, dass die Dateinamen identisch sind. Diese Methode sagt mir jedoch nicht, ob der Inhalt der Dateien identisch ist:

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

Die in dieser ServerFault-Frage beschriebene Technik funktioniert zum Unterschieden einer einzelnen Datei. Diese Ordner enthalten jedoch Hunderte von Dateien in verschiedenen Tiefen.

Die Lösung muss mir nicht unbedingt sagen, was speziell in den Dateien anders ist - nur dass sie es sind. Ich bin nicht an Unterschieden in Metadaten wie dem Datum interessiert, von denen ich bereits weiß, dass sie unterschiedlich sind.

Antworten:


15

Wenn Sie den Vergleich in eine Schleife einwickeln möchten, würde ich den folgenden Ansatz wählen:

$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)

        }
    }   
}

Beachten Sie, dass dadurch Dateien ignoriert werden, die in $folder1 und nicht vorhanden sind $folder2.


5

Ich habe die Antwort von jscott genommen und erweitert, um die Dateien auszugeben, die in der einen, aber nicht in der anderen vorhanden sind, für diejenigen, die an dieser Art von Funktionalität interessiert sind. Bitte beachten Sie, dass es auch Fortschritte zeigt, die gemacht wurden, da es für mich angesichts der riesigen Ordner mit nicht sehr vielen Unterschieden schwer zu erkennen war. Es sah so aus, als wäre das Drehbuch an mich gehängt worden. Hier ist der Powershell-Code dafür:

$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"
    }
}

Warum sollten Sie beim Aufrufen von Compare-Object den tatsächlichen Inhalt einer Datei extrahieren? Das macht Compare-Object. technet.microsoft.com/en-us/library/…
Casper Leon Nielsen

1

Sie wickeln einfach eine Schleife um die richtige Antwort aus Ihrer verknüpften Frage, die diese bereits beantwortet hat, und durchsuchen den Verzeichnisbaum, indem Sie jede Datei mit demselben Namen vergleichen.

/ Bearbeiten: Wenn das tatsächlich Ihre Frage ist, ist es besser für SO geeignet, wo Sie regelmäßig Beiträge zu leisten scheinen. Sie stellen eine Programmierfrage. Ich verstehe, dass Sie dies für einen Sysadmin-Zweck tun. In diesem Fall würde ich Ihnen empfehlen, ein speziell entwickeltes Tool wie WinDiff zu verwenden.


2
OK, diese Seite ist nicht für Fragen vom Typ "Gib mir den Codez" geeignet. Wenn Sie lernen möchten, wie man Loops in Powershell erstellt, kaufen Sie ein Buch oder finden Sie Online-Tutorials. da sind viele.
Mfinni

2
Ich denke, Sie sind auf der falschen Seite des Bettes aufgewacht. Ich bin kein regulärer Powershell-Benutzer. Ich habe in meiner Frage sowohl eine Technik gezeigt, die ich gerade versuche, als auch einen Link zu einer Frage, die zusätzliche hilfreiche Informationen für mein Problem enthält. Ich weiß nicht, wie ich die beiden Techniken kombinieren soll, was mein Problem ist und warum ich diese Frage gestellt habe. Es ist auch eine Frage, die ich mit der Google-Suche nicht beantworten konnte. Wenn Sie nicht hilfreich sein werden, sollten Sie Ihre Antwort löschen.
David Smith

2
@ BigDave Buchstäblich das erste Ergebnis für PowerShell loop through filesGoogle . Komm schon - ein bisschen Mühe von deiner Seite?
voretaq7

2
@ voretaq7 Ich denke ihr versteht mich als PowerShell-Benutzer falsch. Ich habe diese Google-Suche durchgeführt, diese Technik versucht und war nicht erfolgreich. Ich habe versucht zu erklären, wo ich mich in der obigen Frage befinde. Die Frage, mit der Sie verknüpfen, funktioniert für einen einzelnen Satz von Dateien. Ich habe zwei Sätze, die ich vergleichen muss, Name zu Name. Ich versuche hier wirklich nicht faul zu sein. Ich kann schleifen und vergleichen. Wie schleife ich zwei Sätze und vergleiche sie?
David Smith

1
Ich denke, dass dies mit PS ein großartiges kleines Projekt ist. WinMerge (dachte, es wäre WinDiff, dumm von mir) ist jedoch wirklich ein großartiges Tool, wenn Sie dies sehr oft tun werden. Es ist buchstäblich für den Job gebaut. Probieren Sie es aus, der Download ist kostenlos. Es verfügt über Zersetzer für die meisten Dateitypen und eignet sich hervorragend zum Hervorheben, einschließlich Optionen für den Umgang mit Leerzeichen.
Mfinni

0

Mach das:

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

Und sogar rekursiv:

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

und ist sogar schwer zu vergessen :)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.