使用 Import-Csv 将旧 CSV 和新 CSV 读取到单独的变量中,然后调用 Compare-Object 进行比较。确保比较 Hash 和 Path 以检测移动的文件。
$oldHashes = Import-Csv oldhashes.csv
$newHashes = Import-Csv newhashes.csv
Compare-Object $oldHashes $newHashes -Property Hash, Path | Export-Csv difference.csv
作为一种性能优化,您可以在生成新哈希时将它们存储在一个变量中。这样您就不必再次从文件中读取新的哈希值。
如果 CSV 相等,则输出文件“difference.csv”将为空。
否则输出文件包含所有差异。 SideIndicator 列指示 Hash 和 Path 的给定组合是仅存在于 oldhashes.csv (SideIndicator <=) 中还是仅存在于 newhashes.csv (SideIndicator =>) 中。
进一步改进
上面的代码输出重复的路径,以防文件被修改。为了便于阅读,以表格格式输出示例:
Path Hash SideIndicator
---- ---- -------------
C:\test\bar.txt 73FEFFA4B7F6BB68E44CF984C85F6E88 <=
C:\test\baz.txt D41D8CD98F00B204E9800998ECF8427E =>
C:\test\foo.txt 2AF65102DB00B80835E1578278064AD1 =>
C:\test\foo.txt 37B51D194A7513E45B56F6524F2D51F2 <=
文件“foo.txt”被列出两次,因为它以新旧状态存在,但内容有所修改。要删除重复的路径,我们可以使用Group-Object 对Path 属性进行分组:
# Compare and store differences in variable $diff
$diff = Compare-Object $oldHashes $newHashes -Property Path, Hash | Sort-Object
# Group on path to create only a single output item for each modified file
$groupedDiff = $diff | Group-Object Path | ForEach-Object {
# The pscustomobject is the output of the ForEach-Object script block
[pscustomobject] @{
Path = $_.Name
# If group has only one element, the file exists either in old or in new state.
# Otherwise we have a modified file, which will be indicated by
# special SideIndicator value '<>'.
SideIndicator = if( $_.Count -eq 1 ) { $_.Group.SideIndicator } else { '<>' }
}
}
$groupedDiff | Export-Csv difference.csv
$groupedDiff的表格内容:
Path SideIndicator
---- -------------
C:\test\bar.txt <=
C:\test\baz.txt =>
C:\test\foo.txt <>
现在我们只得到“foo.txt”的一行,其中<> 清楚地表明该文件已被修改。我没有输出哈希值,因为在这种输出格式中我看不到它们有多大用处。如果您需要它们,请将属性添加到 [pscustomobject] 并分配 $_.Group.Hash。