【问题标题】:Compare two lists of files and their content比较两个文件列表及其内容
【发布时间】:2014-07-11 17:25:13
【问题描述】:

虽然这看起来很简单(而且可能很简单!)但我似乎找不到解决它的方法。

我要做的是按内容比较两个过滤文件列表。例如,如果两个列表返回说他们在 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

想法或解决方案?

【问题讨论】:

    标签: xml powershell compare config


    【解决方案1】:

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

    $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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-22
        • 2018-03-08
        • 1970-01-01
        • 2014-08-09
        • 2021-06-30
        • 2018-03-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多