如何在Windows Powershell中区分两个文件夹?


11

我正在尝试使用Windows Powershell查找两个文件夹结构的内容差异。我使用以下方法来确保文件名相同,但是该方法不会告诉我文件的内容是否相同:

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

这个ServerFault问题中描述的技术适用于差异化单个文件,但是这些文件夹包含各种深度的数百个文件。

解决方案不一定需要告诉我文件中到底有什么不同-只是它们有所不同。我对元数据中的差异(例如日期)不感兴趣,我已经知道它们是不同的。

Answers:


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/zh-CN/library/…–
卡斯珀·莱昂·尼尔森

1

您只需围绕已回答此问题的链接问题的正确答案环绕一个循环,然后遍历目录树,比较每个具有相同名称的文件。

/ Edit:如果这实际上是您的问题,那么它对于您似乎是常规贡献者的SO更合适。您在问编程问题。我了解您这样做是出于sysadmin类型的目的,在这种情况下,我会告诉您使用WinDiff之类的专用工具。


2
好的,此网站不适用于“给我codez”类型的问题。如果您需要开始学习如何在Powershell中进行循环,请购买书籍或查找在线教程。有许多。
mfinni

2
我想你在床的另一边醒来了。我不是Powershell的普通用户。我已经在问题中展示了我目前正在尝试的一种技术,以及一个指向问题的链接,该链接为我的问题提供了更多有用的信息。我不知道如何结合这两种技术,这是我的问题,也是我提出这个问题的原因。这也是我无法使用Google搜索回答的问题。如果您无济于事,请考虑删除答案。
大卫·史密斯

2
@BigDave 字面上的第一个结果PowerShell loop through files上谷歌。现在就来- 您需要付出一点努力吗?
voretaq7 2013年

2
@ voretaq7我认为你们误解了我作为PowerShell用户的身份。我做了谷歌搜索,尝试了这种技术,但没有成功。我试图解释以上问题的所在。您链接到的问题适用于一组文件。我需要比较两套名称到名称。我真的不是想在这里偷懒。我知道如何循环,也知道如何比较。如何循环并比较两组?
大卫·史密斯

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)

甚至很难忘记:)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.