在 Compare-Object 的相同结果集中进行比较
Compare within same result set of 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"
.[= 的内容20=]
对于第二个文件,qwertyuiop.avi
,它只在源位置而不是在目标位置,它会记录类似 "File missing from destination"
.
的内容
有没有办法直接与 Compare-Object
的输出进行比较?我似乎找不到比较相同输出行之间的好方法。是否需要将数据导出到两个不同的CSV文件,一个用于一侧,另一个用于另一侧,然后进行比较?
编辑:
在 Robert 的帮助下,我使用以下代码对原始 Compare-Object
语句的输出进行分组,并根据 [=19] 的计数为同名文件输出一条消息=] 语句。
$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"
}
}
您可以将输出放在一个变量中。
$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
我有一个 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"
.[= 的内容20=]
对于第二个文件,qwertyuiop.avi
,它只在源位置而不是在目标位置,它会记录类似 "File missing from destination"
.
有没有办法直接与 Compare-Object
的输出进行比较?我似乎找不到比较相同输出行之间的好方法。是否需要将数据导出到两个不同的CSV文件,一个用于一侧,另一个用于另一侧,然后进行比较?
编辑:
在 Robert 的帮助下,我使用以下代码对原始 Compare-Object
语句的输出进行分组,并根据 [=19] 的计数为同名文件输出一条消息=] 语句。
$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"
}
}
您可以将输出放在一个变量中。
$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