Windows Powershell'de iki klasörü nasıl farklılaştırırım?


11

Windows Powershell kullanarak iki klasör yapısının içeriğindeki farklılıkları bulmaya çalışıyorum. Dosya adlarının aynı olmasını sağlamak için aşağıdaki yöntemi kullandım, ancak bu yöntem dosyaların içeriği aynı olup olmadığını bana söylemiyor:

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

Bu ServerFault sorusunda açıklanan teknik, tek bir dosyayı dağıtmak için çalışır, ancak bu klasörler çeşitli derinliklerde yüzlerce dosya içerir.

Çözümün, dosyalarda özel olarak neyin farklı olduğunu söylemesine gerek yoktur - sadece bunlar. Zaten farklı olduğunu bildiğim tarih gibi meta verilerdeki farklılıklarla ilgilenmiyorum.

Yanıtlar:


15

Karşılaştırmayı bir döngüye sarmak istiyorsanız, aşağıdaki yaklaşımı benimserim:

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

        }
    }   
}

Bunun hem $folder1 ve hem de olmayan dosyaları yok sayacağını unutmayın $folder2.


5

Ben jscott'un cevabını aldım, birinde mevcut olan dosyaların çıktısını almak için genişletilmiş, ancak bu tür işlevsellikte en inster olanlar için değil. Lütfen, çok fazla fark olmayan büyük klasörler göz önüne alındığında benim için zor olduğu için kaydedilen ilerlemeyi gösterdiğini unutmayın. Senaryo bana asılmış gibi görünüyordu. İşte bunun için powershell kodu:

$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'i çağırırken neden bir dosyanın gerçek içeriğini çıkarasınız ki? Compare-Object bunu yapar. technet.microsoft.com/tr-tr/library/…
Casper Leon Nielsen

1

Bağlantılı sorunuzdan bunu yanıtlayan doğru cevabın etrafına bir döngü sarmanız ve aynı adla her dosyayı karşılaştırarak dizin ağacında yürümeniz yeterlidir.

/ Edit: Bu aslında sorunuzsa, düzenli bir katkıda bulunduğunuz gibi SO için daha uygundur. Bir programlama sorusu soruyorsun. Sysadmin türü bir amaç için yaptığınızı anlıyorum, bu durumda size WinDiff gibi amaca yönelik bir araç kullanmanızı söyleyebilirim.


2
Tamam, bu site "Bana kodunu ver" tipi sorular için uygun değil. Powershell'de döngüler yapmayı öğrenmeye başlamanız gerekiyorsa, bir kitap satın alın veya çevrimiçi öğreticiler bulun; çok var.
mfinni

2
Sanırım yatağın yanlış tarafında uyandın. Ben normal bir Powershell kullanıcısı değilim. Sorumda hem şu anda denediğim bir tekniği hem de sorunum için ek yararlı bilgiler içeren bir sorunun bağlantısını gösterdim. Benim sorunum olan iki tekniği nasıl birleştireceğimizi ve bu soruyu sormamın nedenini bilmiyorum. Bu aynı zamanda Google aramalarını kullanarak cevaplayamadığım bir soru. Yardımcı olmayacaksanız, lütfen cevabınızı silmeyi düşünün.
David Smith


2
@ voretaq7 Sanırım beni bir PowerShell kullanıcısı olarak yanlış anlıyorsunuz. O google aramasını yaptım, bu tekniği denedim ve başarılı olamadım. Yukarıdaki soruda nerede olduğumu açıklamaya çalıştım. Bağlantı verdiğiniz soru tek bir dosya grubunda çalışır. Karşılaştırmam gereken iki setim var, isim-isim. Burada gerçekten tembel olmaya çalışmıyorum. Döngüyü biliyorum ve nasıl karşılaştırılacağını biliyorum. İki seti nasıl döngü ve karşılaştırırım?
David Smith

1
PS ile bunu yapmanın harika bir proje olduğunu düşünüyorum. Ancak, WinMerge (WinDiff olduğunu düşündüm, aptalca) bunu çok sık yapacaksanız gerçekten harika bir araçtır. Kelimenin tam anlamıyla iş için yapılmış. Deneyin, indirme ücretsizdir. Çoğu dosya türü için ayrıştırıcıya sahiptir ve boşlukları nasıl ele almak istediğinize ilişkin seçenekler de dahil olmak üzere harika bir vurgulama işi yapar.
mfinni

0

Bunu yap:

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

Ve hatta özyineli olarak:

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

ve unutmak bile zor :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.