比较两个文件列表及其内容

时间:2014-05-22 15:14:23

标签: xml powershell compare config

虽然这看起来很简单(也可能是这样!)但我似乎无法找到解决问题的方法。

我要做的是按照内容比较两个过滤文件列表。这样做的一个例子是,如果两个列表回来说他们在Stuff \ files \ morefiles位置有一个名为file.config的项目,那么这会将这些文件进行比较并输出更改的位置和内容。本质上,执行.config文件的差异并显示更改的位置。这对于比较两个文件(比较对象等可以使用)通常很简单,但是因为它是两个文件列表而不是单个文件我不知所措。

我需要这样做以显示在软件升级中配置文件所需的所有更改的列表,因此从一个版本的软件到下一个版本,对配置文件进行了哪些更改。我在powershell中这样做是因为它能够轻松地与HG mercurial交互并由经验不足的用户(通过bat文件)运行。

目标是有一个.txt文件,列出新安装中与旧版本相比更改的所有文件或类似内容。

这是我到目前为止所拥有的:

$A = Get-ChildItem -Recurse -path "C:\repos\Dev\Projects\Bat\CurrentVersionRepoCloneTemp" -filter "*.config"

$B = Get-ChildItem -Recurse -path "C:\repos\Dev\Projects\Bat\UpgradeVersionRepoCloneTemp" -filter "*.config"

$C = Compare-Object $A $B -Property ('Name', 'Length') -PassThru | Where-Object {$_.FullName -eq $_.FullName} | ForEach-Object 
{    
    Compare-Object (Get-Content FileA)(Get-Content FileB) #I know this doesn't work 
}$C

想法或解决方案?

2 个答案:

答案 0 :(得分:3)

你可以做一个checksum of each file并比较一下......

$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($file)))

答案 1 :(得分:2)

Tim Ferrill检查更新文件的想法似乎是比较文件的更好方法。做点什么

$A = Get-ChildItem -Recurse -path "C:\repos\Dev\Projects\Bat\CurrentVersionRepoCloneTemp" -filter "*.config"
$B = Get-ChildItem -Recurse -path "C:\repos\Dev\Projects\Bat\UpgradeVersionRepoCloneTemp" -filter "*.config"
$A | %{$_ | Add-Member "MD5" ([System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($_))))}
$B | %{$_ | Add-Member "MD5" ([System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($_))))}

然后我会进行比较和分组目录。

$C = Compare-Object $A $B -Property ('Name', 'MD5') - Passthrough | Group Directory

在那之后,获得实际的变化,这将会有点慢。对文件内容进行逐行匹配是很粗糙的,但如果它们不是太大,它仍然应该在眨眼之间发生。我建议像:

$Output = @()
ForEach($File in $C[1].Group){
    $OldData = GC $File
    $C[0].Group | ?{$_.Name -eq $File.Name} | %{
        $NewData = GC $_
        $UpdatedLines = $NewData | ?{$OldData -inotcontains $_}
        $OldLines = $OldData | ?{$NewData -inotcontains $_}
        $Output += New-Object PSObject -Property @{
            UpdatedFile=$_.FullName
            OriginalFile=$File.FullName
            Changes=$UpdatedLines
            Removed=$OldLines
        }
    }
}

一旦你拥有了它,你只需要用可读的东西输出它。也许是这样的:

Get-Date | Out-File "C:\repos\Dev\Projects\Bat\UpgradeVersionRepoCloneTemp\ChangeLog.txt"
$Output|%{$_|FT OriginalFile,UpdatedFile; "New/Changed Lines"; "-----------------"; $_.Changes; " "; "Old/Removed Lines"; "-----------------"; $_.Removed} | Out-File "C:\repos\Dev\Projects\Bat\UpgradeVersionRepoCloneTemp\ChangeLog.txt" -Append
相关问题