Як я відрізняю дві папки в Windows Powershell?


11

Я намагаюся знайти відмінності у вмісті двох структур папок за допомогою Windows Powershell. Я використовував наступний метод, щоб переконатися, що імена файлів однакові, але цей метод не підказує мені, чи вміст файлів однаковий:

$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 розширив її, щоб вивести файли, які присутні в одному, а не в іншому для тих, хто стикається з цим типом функціональності. Зауважте, він також показує прогрес, досягнутий, оскільки мені було важко бачити, що враховуючи величезні папки з не дуже великими відмінностями. Схоже, сценарій був повішений мені. Ось код повноважень для цього:

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

Чому ви витягуєте фактичний вміст файлу при виклику Порівняти-Об'єкт? Ось що робить Порівняльний об’єкт. technet.microsoft.com/en-us/library/…
Каспер Леон Нільсен

1

Ви просто обмотаєте цикл навколо правильної відповіді на пов’язане запитання, яке вже відповіло на це, і пройдете дерево каталогів, порівнюючи кожен файл з тим же ім’ям.

/ Редагувати: Якщо це насправді ваше питання, то більше підходить для ТА, де ви, здається, регулярно працюєте. Ви задаєте програмне запитання. Я розумію, що ви робите це для цілей системи sysadmin, і в такому випадку я б сказав вам використовувати такий інструмент, як WinDiff.


2
Гаразд, цей сайт не підходить для питань типу "Дайте мені кодек". Якщо вам потрібно почати вивчати, як робити петлі в Powershell, придбайте книгу або знайдіть підручники в Інтернеті; тут багато.
mfinni

2
Думаю, ти прокинувся з виворітного боку ліжка. Я не є звичайним користувачем Powershell. У своєму питанні я продемонстрував як техніку, яку зараз намагаюся, так і посилання на запитання, що містить додаткову корисну інформацію для моєї проблеми. Я не знаю, як поєднувати дві методики, що є моєю проблемою, і причина, по якій я задав це питання. Це також питання, на яке я не зміг відповісти, використовуючи пошук Google. Якщо ви не збираєтеся бути корисними, будь ласка, видаліть свою відповідь.
Девід Сміт

2
@BigDave Буквально перший результат для PowerShell loop through filesGoogle . давай зараз - трохи зусиль з твого боку?
voretaq7

2
@ voretaq7 Я думаю, ви, неправильно, зрозуміли мене як користувача PowerShell. Я здійснив пошук в Google, спробував цю техніку, і не досяг успіху. Я намагався пояснити, де я в цьому питанні. Питання, яке ви посилаєте, працює на одному наборі файлів. У мене є два набори, які мені потрібно порівняти, ім’я-на-ім’я. Я тут справді не намагаюся бути лінивим. Я знаю, як циклічно, і я знаю, як порівнювати. Як зробити цикл та порівняти два набори?
Девід Сміт

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)

і навіть важко забути :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.