我很难弄清楚 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