我在 Compare-Object 方面遇到了一些问题。我的任务是获取在不同时间制作的两个目录快照之间的差异。第一个快照的拍摄方式如下:
ls -recurse d:\dir | export-clixml dir-20100129.xml
然后,稍后我获取第二张快照并加载它们两个:
$b = (import-clixml dir-20100130.xml)
$a = (import-clixml dir-20100129.xml)
接下来,我尝试与 Compare-Object 进行比较,如下所示:
diff $a $b
我得到的结果是,有些地方的文件自 $a 以来添加到了 $b,但有些地方的文件在两个快照中都有,有些文件添加到了 $b,但在 Compare-Object 输出中没有给出。令人费解的是,但 $b.count - $a.count 是确切地与 (diff $a $b).count 相同。这是为什么呢?
好的,Compare-Object 有 -property 参数。我尝试使用它:
diff -property fullname $a $b
我得到了所有的差异:它告诉我全部文件。例如,假设 $a 包含:
A\1.txt
A\2.txt
A\3.txt
$b 包含:
X\2.mp3
X\3.mp3
X\4.mp3
A\1.txt
A\2.txt
A\3.txt
diff 输出类似于以下内容:
X\2.mp3 =>
A\1.txt <=
X\3.mp3 =>
A\2.txt <=
X\4.mp3 =>
A\3.txt <=
A\1.txt =>
A\2.txt =>
A\3.txt =>
很奇怪。我觉得我不明白 Compare-Object 用法的一些关键内容,而且手册很少……请帮我获取 不同之处两个目录快照之间。提前致谢
更新:我已将数据保存为如下纯字符串:
> import-clixml dir-20100129.xml | % { $_.fullname } | out-file -enc utf8 a.txt
结果是一样的。以下是两个快照(前 100 多行,a.txt 和 b.txt)、compare-object 的输出以及 UNIX diff 的输出(统一)的摘录。所有文件均为 UTF-8:http://dl.dropbox.com/u/2873752/compare-object-problem.zip
答案1
可以使用 -SyncWindow 参数解决该问题。相比之下,该值应该是最小集合长度的一半:
> Compare-Object -SyncWindow ($a.length / 2) $a $b
来源:http://dmitrysotnikov.wordpress.com/2008/06/06/compare-object-gotcha/
答案2
这是由于 export-clixml/import-clixml 造成的。它实际上将每个文件对象的类型从 System.IO.FileSystemInfo 更改为 Deserialized.System.IO.FileInfo。
让你的第二个 ls 命令将 export-clixml 导出到一个临时文件,然后导入并与之进行比较,这样应该可以解决问题。
答案3
我发现的一个很好的例子就是这个。
获取服务的原始状态:
$before = get-service
现在对服务进行一些更改,例如关闭 1 并启动 1。
获取服务的新状态:
$after = get-service
然后比较两个列表(diff 是 Compare-Object 的别名):
diff $before $after -property name,status
示例结果:
PS> diff $before $after -property name,status
name status SideIndicator
---- ------ -------------
Spooler Stopped =>
Spooler Running <=
用 <= 展示第一个对象,用 => 展示第二个对象的变化。或者只是前后视角。您还可以创建标签和表达式,以在出现 => 时显示“已更改”字样。
使用此功能,您还可以在比较中看到某些内容在第一个列表中但在第二个列表中的情况。非常类似于查找不匹配查询。
答案4
就我个人而言,我发现如果你能先排序,diff 效果会更好
尝试
$b = (import-clixml dir-20100130.xml) | sort
$a = (import-clixml dir-20100129.xml) | sort
diff $a $b