如何在 powershell 5.1 中比较两个文件夹?

如何在 powershell 5.1 中比较两个文件夹?

我很难弄清楚 PS 想要告诉我什么。我创建了一个脚本,用于比较两个目录中的文件。我想输出任一目录中的名称、文件数量或长度的任何差异。最终,如果存在差异,我希望它会出错。以下是我所拥有的:

Write-host "$(Get-Date) - Comparing $deploy_src\bin $deploy_dst\bin"
$bin_src = Get-ChildItem $deploy_src
$bin_dst = Get-ChildItem $deploy_dst

if (Compare-Object $bin_src.Name $bin_dst.Name) {
   # throw "Directories differ"
}

以下是我看到的(没什么帮助的)输出:

02/24/2020 09:57:36 - Comparing J:\AdvantageProxy\Development\bin J:\AdvantageProxy\Deploy-QA-2020-02-21\bin
02/24/2020 09:57:36 - done.
Name Length SideIndicator
---- ------ -------------
         38 =>           
         20 <= 

更新:这些文件位于 Mac 可访问的 FSx 共享上。这是 diff 的输出,它仅显示可直接从 Mac 访问的目录中的 .DS_Store:

 $ rsync -n -a -i --delete /Volumes/share/AdvantageProxy/Development/bin/. /Volumes/share/AdvantageProxy/Deploy-QA-2020-02-21/bin/.
 *deleting   .DS_Store
 .d..t....... ./
 .d..t....... de/
 .d..t....... es/
 .d..t....... ja/
 .d..t....... ru/

(我使用 rsync 以避免花时间进行 diff 比较文件内容...这表明 $deploy_dst\bin 中有一个文件不在 $deploy_src\bin 中,并且几个文件夹上的时间戳不同。我希望看到与 Powershell 解决方案类似的内容。)

还要注意 - 如果可能的话,我尽量避免安装额外的依赖项,这就是我尝试通过 PS 来执行此操作的原因。

答案1

我最终创建了自己的解决方案。其相关部分如下所示:

      function Compare_Directory
      {
          [CmdletBinding()]
          Param(
               [string]
              [Parameter(Mandatory=$true)]
              $src_dir,
              [Parameter(Mandatory=$true)]
              [string]
              $dest_dir
          )

          Write-Host "$(Get-Date) - Diffing files in $src_dir to $dest_dir (will only report differences)"

          # Get .FullName to avoid issues with string replace not matching FullName to non-full file names (ie, paths using PSdrives)
          $src_str = (Get-Item $src_dir).FullName
          $dest_str = (Get-Item $dest_dir).FullName

          if ($verbose>1){
            Write-Host "$(Get-Date) - $src_str -> $dest_str"
          }

          # Get all files under $folder1, filter out directories
          $src_files = Get-ChildItem  $src_dir -force | Where-Object { -not $_.PsIsContainer }  # -Recurse
          # -force will pick up dotfiles (or windowspeak, files with the hidden attribute set)

          $i=0
          $mismatches=0
          $src_files | ForEach-Object {

                  $src_fl = (Get-Item $_.FullName -force)
                  $dest_flnm = $_.FullName.replace($src_str, $dest_str)
                  $dest_fl = (Get-Item $dest_flnm -force)

                  # Currently, this will cause an error if a file exists in src directory but not dest directory
                  # I don't know how to write this so that it can error more than once depending on verbosity 
                  #   like the rest of the script and it's not a priority for me.

                  if ($verbose>1){
                    Write-Host "$src_fl ?? $dest_fl"
                  }

                  If ( Compare-Object $src_fl $dest_fl -Property Name, Length ) {

                      # List files not matching
                      Write-Host "src- $src_fl"
                      Write-Host "dest- $dest_fl"

                      # if verbosity <0, fail fast, otherwise provide maximum insight (logging)
                      if ($verbose -lt 0){
                        throw "Verbosity set to intolerant; First mismatch found- $src_fl"
                      }
                      else{
                        $mismatches+=1
                      }

                  }
          }
          Write-Host "$i files compared"
          if ($mismatches -gt 0){
            throw "Mismatching files found: $mismatches"
          }
      }

      # Diff directories in both directions to identify differences in file names

      Write-host "$(Get-Date) - Comparing $backup_src and $deploy_dst (->)"
      Compare_Directory $backup_src $deploy_dst
      Write-host "$(Get-Date) - Comparing $backup_src and $deploy_dst (<-)"
      Compare_Directory $deploy_dst $backup_src

      Write-host "$(Get-Date) - Comparing $deploy_src\bin $deploy_dst\bin (->)"
      Compare_Directory $deploy_src\bin $deploy_dst\bin
      Write-host "$(Get-Date) - Comparing $deploy_src\bin $deploy_dst\bin (->)"
      Compare_Directory $deploy_dst\bin $deploy_src\bin

相关内容