it-swarm-ru.tech

Как мне различить два текстовых файла в Windows Powershell?

У меня есть два текстовых файла, и я хочу найти различия между ними с помощью Windows Powershell. Есть ли что-то похожее на инструмент сравнения Unix? Или есть другой способ, который я не рассмотрел?

Я пробовал сравнить объект, но получить этот загадочный вывод:

PS C:\> compare-object one.txt two.txt

InputObject                                                 SideIndicator
-----------                                                 -------------
two.txt                                                     =>
one.txt                                                     <=
104
Brian Willis

Сам разобрался. Поскольку Powershell работает с объектами .net, а не с текстом, вам необходимо использовать get-content для отображения содержимого текстовых файлов. Чтобы выполнить то, что я пытался сделать в этом вопросе, используйте:

compare-object (get-content one.txt) (get-content two.txt)
110
Brian Willis

Более простой способ сделать это - написать:

diff (cat file1) (cat file2)
34
Alex Y.

Или вы можете использовать команду DOS fc примерно так (это показывает вывод обоих файлов, поэтому вам придется искать различия):

fc.exe filea.txt fileb.txt > diff.txt

fc является псевдонимом для командлета Format-Custom, поэтому обязательно введите команду как fc.exe. Обратите внимание, что многие утилиты DOS не поддерживают кодировку UTF-8.

Вы также можете запустить процесс CMD и запустить внутри него fc.

start cmd "/c  ""fc filea.txt fileb.txt >diff.txt"""

Это указывает PowerShell запустить процесс с помощью программы cmd, используя параметры в кавычках. В кавычках есть опция '/ c' cmd для запуска команды и завершения. Фактическая команда для запуска cmd в процессе: fc filea.txt fileb.txt перенаправить вывод в файл diff.txt.

Вы можете использовать DOS fc.exe изнутри powershell.

32
phord350

diff on * nix не является частью оболочки, а является отдельным приложением.

Есть ли причина, по которой вы не можете просто использовать diff.exe под PowerShell?

Вы можете скачать версию из пакета UnxUtils ( http://unxutils.sourceforge.net/ )

7
Mikeage

сравнивать объект (он же diff) является жалким, если вы ожидаете, что он будет вести себя как Unix Diff. Я попробовал diff (gc file1) (gc file2), и если строка слишком длинная, я не вижу фактического diff и, что более важно, я не могу сказать, на каком номере строки находится diff.

Когда я пытаюсь добавить -passthru, я теперь вижу разницу, но я теряю, в каком файле находится разница, и все равно не получаю номер строки.

Мой совет, не используйте PowerShell, чтобы найти различия в файлах. Как кто-то еще заметил, fc работает и работает немного лучше, чем Compare-Object, и еще лучше загружает и использует реальные инструменты, такие как эмулятор Unix, который упоминал Mikeage.

4
Marc Towersap

Как уже отмечали другие, если вы ожидаете вывод unix-y diff, то использование псевдонимов powershell сильно подведет вас. Во-первых, вы должны держать руку на деле при чтении файлов (с помощью gc/get-content). С другой стороны, индикатор разницы справа, вдали от контента - это кошмар читабельности.

Решение для тех, кто ищет вменяемый вывод:

  1. получить реальный diff (например, от GnuWin32)
  2. edit% USERPROFILE%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
  3. добавить строку

    remove-item alias:diff -force
    

Аргумент -force необходим, потому что Powershell весьма ценен в этом конкретном встроенном псевдониме. Если кому-то интересно, установив GnuWin32, я также добавлю следующее в свой профиль powershell:

remove-item alias:rm
remove-item alias:mv
remove-item alias:cp

Главным образом потому, что Powershell не понимает аргументы, которые запускаются вместе и вводят, например, "rm -Force -Recurse" - это гораздо больше усилий, чем "rm -rf".

У Powershell есть некоторые приятные функции, но есть некоторые вещи, которые он не должен делать для меня.

3
daf

WinMerge - еще один хороший инструмент сравнения на основе графического интерфейса.

2
Andy White

_fc.exe_ лучше подходит для сравнения текста, поскольку он предназначен для работы подобно * nix diff, то есть сравнивает строки последовательно, показывая реальные различия и пытаясь выполнить повторную синхронизацию (если различные разделы имеют разную длину). Он также имеет несколько полезных опций управления (текстовый/двоичный, чувствительность к регистру, номера строк, длина ресинхронизации, размер буфера несоответствия) и обеспечивает состояние выхода (-1 неправильный синтаксис, 0 файлов одинаковы, 1 файл отличается, 2 файла отсутствуют). Будучи (очень) старой утилитой DOS, она имеет несколько ограничений. В частности, он не работает автоматически с Юникодом, рассматривая 0 MSB ASCII символов как терминатор строки, поэтому файл становится последовательностью из 1 строки символов (@kennycoc: используйте параметр/U чтобы указать оба файла - Unicode, WinXP и далее), он также имеет размер буфера жесткой строки 128 символов (128 байтов ASCII, 256 байтов Unicode), поэтому длинные строки разделяются и сравниваются по отдельности.

объект сравнения предназначен для определения, являются ли 2 объекта идентичными по элементам. если объекты являются коллекциями, то они обрабатываются как наборы (см. справочный объект сравнения), т. е. коллекции UNORDERED без дубликатов. 2 набора равны, если они имеют одинаковые элементы, независимо от порядка или дублирования. Это сильно ограничивает его полезность для сравнения текстовых файлов на предмет различий. Во-первых, поведение по умолчанию собирает различия до тех пор, пока не будет проверен весь объект (файл = массив строк), что приведет к потере информации, касающейся положения различий, и сокрытию различий в парах (и нет понятия номера строки для SET строк). Использование -synchwindow 0 приведет к тому, что различия будут генерироваться по мере их возникновения, но не будет пытаться выполнить повторную синхронизацию, поэтому, если в одном файле есть дополнительная строка, последующие сравнения строк могут завершиться неудачей, даже если файлы в противном случае идентичны (пока не будет компенсатор дополнительная строка в другом файле, выравнивая соответствующие строки). Тем не менее, PowerShell является чрезвычайно универсальным и полезное сравнение файлов может быть сделано с помощью этой функциональности, хотя и за счет существенной сложности и с некоторыми ограничениями на содержание файлов. Если вам нужно сравнить текстовые файлы с длинными (> 127 символов) строками и в которых строки в основном совпадают 1: 1 (некоторые изменения в строках между файлами, но без дублирования в файле, такие как текстовый список записей базы данных, имеющих ключевое поле) затем, добавив информацию в каждую строку, указав, в каком файле он находится, его положение в этом файле, а затем проигнорировав добавленную информацию во время сравнения (но включив ее в выходные данные), вы можете получить * nix diff-подобный вывод следующим образом (используются псевдонимы сокращения ):

_diff (gc file1 | % -begin { $ln1=0 } -process { '{0,6}<<:{1}' -f ++$ln1,$_ }) (gc file2 | % -begin { $ln2=0 } -process { '{0,6}>>:{1}' -f ++$ln2,$_ }) -property { $_.substring(9) } -passthru | sort | out-string -width xx
_

где хх - длина самой длинной строки + 9

Объяснение

  • _(gc file | % -begin { $ln=0 } -process { '{0,6}<<:{1}' -f ++$ln,$_ })_ получает содержимое файла и предварительно добавляет номер строки и индикатор файла (<< или >>) к каждой строке (используя оператор строки формата) перед передачей его в diff.
  • -property { $_.substring(9) } говорит diff сравнивать каждую пару объектов (строк), игнорируя первые 9 символов (которые являются номером строки и индикатором файла). При этом используется возможность указать вычисляемое свойство (значение блока скрипта) вместо имени свойства.
  • _-passthru_ заставляет diff выводить разные входные объекты (которые включают номер строки и индикатор файла) вместо отличающихся сравниваемых объектов (которые этого не делают).
  • _sort-object_ затем переводит все строки в последовательность.
    out-string останавливает усечение вывода по умолчанию, чтобы соответствовать ширине экрана (как отметил Марк Тауэрсап), указав ширину, достаточно большую, чтобы избежать усечения. Обычно этот вывод помещается в файл, который затем просматривается с помощью прокручиваемого редактора (например, блокнота).

Запись

Формат номера строки {0,6} дает выравниваемый справа пробел номер строки из 6 символов (для сортировки). Если файлы имеют более 999 999 строк, просто измените формат на более широкий. Это также требует изменения параметра _$_.substring_ (на 3 больше ширины номера строки) и внешнего значения xx (максимальная длина строки + параметр _$_.substring_).

1
codemaster bob

Также есть Windiff , который обеспечивает интерфейс с графическим интерфейсом (отлично подходит для использования с программами CVS/SVN на основе GUI)

1
saschabeaumont