虽然这看起来很简单(也可能是这样!)但我似乎无法找到解决问题的方法。
我要做的是按照内容比较两个过滤文件列表。这样做的一个例子是,如果两个列表回来说他们在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
想法或解决方案?
答案 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)
$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