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