首页 > 解决方案 > 在 Compare-Object 的同一结果集中进行比较

问题描述

我有一个 CSV 文件,其中包含我的一个存储设备上的每个文件的名称、大小和哈希(文件名、字节大小和 MD5 哈希)。移动此数据后,我将为每个文件生成哈希,包括名称和大小,然后将这些列与现有 CSV 中的列进行比较。我知道有一些实用程序可以为我完成所有这些工作,但我这样做更多的是作为一种学习经验而不是其他任何事情。

我想做的是对于不完全匹配的文件名、大小和哈希,我想导出一个日志,指示该文件是否在新位置不存在,或者是否存在哈希不匹配。

例如,使用我当前的比较脚本:

$csv1 = Import-CSV "X:\Documents\Customer Projects\Destination.csv"
$csv2 = Import-CSV "X:\Documents\Customer Projects\Source.csv"
Compare-Object -ReferenceObject $csv2 -DifferenceObject $csv1 -Property Name,Size,Hash

我得到:

Name                                            Size                                            Hash                                            SideIndicator                                 
----                                            ----                                            ----                                            -------------                                 
123456789.avi                                   4122896                                         D258518EDDE5F00579CE2F9D01129C11                =>                                            
123456789.avi                                   8635210                                         807666D37D0E1A75279E1AE837759674                <=                                            
qwertyuiop.avi                                  468246867                                       3F779E039B646D49D84F3D2C403F2EBD                <=

在第一个文件的情况下123456789.avi,它在两个位置都可以找到,但是大小和哈希不匹配,应该记录一些类似的内容"Hash mis-match"

对于第二个文件,qwertyuiop.avi它仅位于源位置而不是目标位置,它会记录类似"File missing from destination".

有没有办法直接与输出进行比较Compare-Object?我似乎找不到在相同输出的行之间进行比较的好方法。是否需要将数据导出到两个不同的 CSV 文件,一个用于一侧,另一个用于另一侧,然后进行比较?


编辑

在 Robert 的帮助下,我使用以下代码对原始Compare-Object语句的输出进行分组,并根据语句的计数为同名文件输出一条消息Group-Object

$csv1 = Import-CSV "X:\Documents\Customer Projects\Destination.csv"
$csv2 = Import-CSV "X:\Documents\Customer Projects\Source.csv"
$test = Compare-Object -ReferenceObject $csv2 -DifferenceObject $csv1 -Property Name,Size,Hash
$group = $test | Group-Object -Property Name
foreach ($file in $group)
{
    if (($file | Select-Object -ExpandProperty Count) -ge 2) {
        Write-Host ""$file.name"- Hash mis-match"
    }
    if (($file | Select-Object -ExpandProperty Count) -eq 1) {
        Write-Host ""$file.name"- File missing"
    }
}

标签: powershellpowershell-4.0

解决方案


您可以将输出放入变量中。

$compare = compare-object ....

然后您可以根据名称运行循环并搜索重复项

Foreach ($file in $compare.name) {
    If (($compare.name -match $file).count -ge 2) {
        "Perform action based on file"
    }
}

我希望这有帮助。

if 语句的另一个选项是

(($compare | where name -eq $file).count -ge 2)

如果您想将计数搜索设置为-eq 1您可以使用它来以不同的方式记录。

另一种选择是将您的比较对象通过管道传输到组对象中,并将 2 用于一条消息,将 1 用于另一条消息。让我知道您是否愿意这样做。group-object 的优点是它不会给你两次相同的消息。原来我正在构建的脚本需要类似的东西。这就是我的做法。(当然根据您的需要简化)

$csv1 = Import-CSV "X:\Documents\Customer Projects\Destination.csv"
$csv2 = Import-CSV "X:\Documents\Customer Projects\Source.csv"
$compare = Compare-Object -ReferenceObject $csv2 -DifferenceObject $csv1 -Property Name,Size,Hash
#this next line finds duplicate errors
$findings = group-object $compare -property name | where count -ge 2
foreach  ($finding in $findings) {
    $expand = $finding | select -ExpandProperty group | select -expand name -first 1
    $compare | where name -match $expand | Add-Member -MemberType NoteProperty -Name Notes -Value "Hashes don't match" -force
}
$compare | where Notes -match ".." | select Name,Size,Hash,Notes  | export c:\compare.csv

推荐阅读