Compare-Object дает ложные различия

У меня есть некоторые проблемы с 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 

В некоторых местах я получаю файлы, которые были добавлены в $b после $a, но в некоторых - файлы, которые были в обоих моментальных снимках, и некоторые файлы, которые были добавлены в $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 => 

Weird. Я думаю, что я не понимаю что-то решающее в использовании Compare-Object, а руководств мало... Пожалуйста, помогите мне получить РАЗНИЦУ между двумя снимками каталогов. заранее спасибо

ОБНОВЛЕНИЕ: я сохранил данные в виде простых строк, как это:

> import-clixml dir-20100129.xml | % { $_.fullname } | out-file -enc utf8 a.txt

И результаты одинаковы. Вот выдержки из обоих снимков (верхние 100 с чем-то строк, a.txt и b.txt), выходные данные объекта сравнения и выходные данные UNIX diff (унифицированные). Все файлы в формате UTF-8: http://dl.dropbox.com/u/2873752/compare-object-problem.zip

4 ответа

Решение

Решить проблему можно с помощью параметра -SyncWindow. Значение должно быть на половину длины наименьшей коллекции по сравнению:

> Compare-Object -SyncWindow ($a.length / 2) $a $b

Источник: http://dmitrysotnikov.wordpress.com/2008/06/06/compare-object-gotcha/

Вот хороший пример, который я нашел.

Получить исходный статус для услуг:

$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 <=

Демонстрирует 1-й объект с <=, 2-й объект изменения, видимый с a =>. Или просто до и после перспективы. Вы также можете создать метку и выражение для отображения слова "Изменено" в случае, если есть =>.

Используя это, вы также можете видеть в сравнении, когда что-то находится в первом списке, но было во втором. Очень похоже на поиск несоответствия.

Это связано с export-clixml/import-clixml. Фактически он изменяет тип каждого файлового объекта с System.IO.FileSystemInfo на Deserialized.System.IO.FileInfo.

Сделайте вторую команду ls export-clixml во временный файл, затем импортируйте и сравните с этим, и это должно решить проблему.

Лично я считаю, что diff работает лучше, если вы можете сначала отсортировать

Пытаться

$b = (import-clixml dir-20100130.xml) | sort
$a = (import-clixml dir-20100129.xml) | sort
diff $a $b
Другие вопросы по тегам