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

3
虽然这看起来可能很简单(也许确实如此!),但我似乎找不到解决方法。
我的目标是比较两个经过筛选的文件列表的内容。一个例子是,如果有两个列表返回表示在Stuff\files\morefiles位置下都有一个名为file.config的项目,则会将这些文件进行比较,并输出更改的位置和内容。本质上,对.config文件进行差异比较,并显示其更改的位置。正常情况下,比较两个文件很简单(可以使用Compare-Object等命令),但由于它是两个文件列表,而不是单个的文件,因此我已经失去了方向。
我需要这样做是为了显示升级软件所需的所有配置文件更改列表,因此从软件的一个版本到另一个版本,哪些更改应用于配置文件。我正在使用PowerShell进行操作,因为可以轻松与HG Mercurial进行交互,并且可以由不太有经验的用户(通过批处理文件)运行。
目标是生成一个列出新安装中更改的所有文件的文本文件或类似文件。
以下是我的进展:
$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个回答

3
你可以对每个文件进行校验和,然后进行比较...
$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($file)))

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接