Сравните два текстовых файла и запишите различия в текстовый файл - PullRequest
0 голосов
/ 07 февраля 2019

Я хочу сравнить 2 текстовых файла и вывести разницу в другом текстовом файле.

$Location = "c:\temp\z.txt"
compare-object (get-content c:\temp\hostname_old.txt) (get-content c:\temp\hostname_new.txt) | format-list | Out-File $Location

hostname_old.txt

server02
server05
server04
server06
server01

hostname_new.txt

server04
server01
server02

Результаты

InputObject   : server05
SideIndicator : <=

InputObject   : server06
SideIndicator : <=

Это то, что я хочу: (избавиться от InputObject и SideIndicator)

server05
server06

Примечание. Связанная проблема, когда один входной файл содержит повторяющиеся записи, - этопредмет этот вопрос .

Ответы [ 3 ]

0 голосов
/ 07 февраля 2019

Я думаю, вы ищете Select-Object -ExpandProperty InputObject

compare-object (get-content c:\temp\hostname_old.txt) (get-content c:\temp\hostname_new.txt) | Select-Object -ExpandProperty InputObject | Out-File $Location

Обратите внимание, что вы не можете использовать format-list в Pipeline перед записью данных в файл.

0 голосов
/ 07 февраля 2019

Просто используйте параметр -PassThru :

compare-object (get-content c:\temp\hostname_old.txt) (get-content c:\temp\hostname_new.txt) -PassThru | Out-File $Location

делает именно то, что вы хотите.

0 голосов
/ 07 февраля 2019

Обновление : Полезный ответ Palle Due предлагает лучшее решение.
Этот ответ все еще может представлять интерес для противопоставления перечисления членов использованию конвейера, обсуждения форматирования вывода,и контрастирование Out-File с Set-Content.


В PSv3 + вы можете просто использовать перечисление члена для извлечения значений .InputObject:

PS> (Compare-Object (Get-Content old.txt) (Get-Content new.txt)).InputObject
server05
server06

Примечание:

  • Перечисление членов удобно и быстро, но за счет потребления памяти, что может быть проблемой для очень больших коллекций (не здесь).Выходные данные Compare-Object должны быть собраны в памяти в целом в массиве ([object[]]), и аналогичным образом значения свойств .InputObject возвращаются в виде массива.

  • Для более медленной, но дружественной памяти (потоковой обработки) используйте конвейер с Select-Object -ExpandProperty, как в эффективном решении TobyU .

Re сохранение в файл : трубопровод в Out-File $location (или, более кратко, с использованием перенаправления вывода: > $location) достаточно - не нужно Format-List.

В общем, обратите внимание, что целью командлетов Format-* является создание выходных данных для display , а не для программной обработки и сохранения.

Тем не менее, Out-File / > (эффективно) с помощью командлетов Format-* за кадром создает строковое представление входных объектов, так же как и вывод консоли по умолчанию, поэтому неправильная команда для сохранения произвольных входных объектов.

Использование Out-File/ > с строками безопасен, однако , потому что они выводятся как есть.Напротив, четные числа проблематичны, если они имеют десятичные разряды, потому что они строковые с десятичным разделителем текущей культуры (например, , вместо . в некоторых культурах).

Если вашвходными объектами являются строки , вы также можете использовать Set-Content, что быстрее, чем Out-File / >, но предостережение заключается в том, что в Windows PowerShell кодировка символов, используемая по умолчанию, отличается:Out-File / > создает файлы UTF-16LE по умолчанию, тогда как Set-Content использует кодовую страницу "ANSI" устаревшей языковой системы (как правило, однобайтовую 8-битную кодировку, например Windows-1252).
Напротив, в PowerShell Core оба командлета выдают UTF-8 без спецификации.

Обратите внимание, что Set-Content, в отличие от Out-File, структурирует нестроковые объекты, просто вызывая .ToString() метод на них.

...