Powershell сравнить два файла
в цсв файлах все разделено табами
Изначально скрипт ругался на пустое значение -Append и я его удалил.Так же изменил разделители на ";"
Получилось:
if(test-path c:\tmp\unique_emails.csv)
$1csv = Import-Csv C:\tmp\mail_old.csv -Delimiter ";"
$2csv = Import-Csv C:\tmp\mail_new.csv -Delimiter ";"
foreach ($line in $1csv)>
В итоге скрипт отрабатывает без ошибок но:
1) Файл "unique_emails.csv" показывает только одну строку с отличием, при чём ту что была последней в файле "mail_old.csv".
2) Все русские имена и фамилии превратились в знаки вопроса. 1 случается из-за отсутствия -append ключа. у него нет значения, он там только для того, чтобы указать команде, что нужно добавлять строки в файл, а не перезаписывать его одной строкой на каждом проходе цикла.
2. попробуйте обновить повершелл до 5.1 ($psversiontable) если он старый. попробуйте ввести ключ -encoding в команду export-csv.
azarij, Сделал исправления: добавил -append -encoding и обновил версию ps.
if(test-path c:\tmp\unique_emails.csv)
$1csv = Import-Csv C:\tmp\mail_old.csv -Delimiter ";"
$2csv = Import-Csv C:\tmp\mail_new.csv -Delimiter ";"
foreach ($line in $1csv)>
Проблема с Кириллицей решилась, но после добавления ключа -append, другая проблема изменилась. Теперь файл unique_emails.csv точная копия файла "mail_old.csv", даже вес файла в КБ одинаковый.
Верхняя строчка обоих файлов:
Не знаю имеет ли значение, но один и тот же email может находится на совершенно разных строчках файлов. Т.е. например user@email.ru может находится на 10 строчке файла "mail_old.csv", а в файле "mail_new.csv" он может находится на 2000-й строчке.
странно. ладно. натравите скрипт на следующие два файла:
1.csv
"name";"email";"phone"
"ak";"ak@ak.com";"0123456"
"kb";"kb@kb.com";"98543221"
"akk";"akk@akk.com";"0123456"
"kak";"kak@kak.com";"98543221"
"aak";"aak@aak.com";"0123456"
"kka";"kka@kka.com";"98543221"
"aka";"aka@aka.com";"0123456"
"kakk";"kakk@kakk.com";"98543221"
2.csv
"name";"email";"phone"
"ak";"ak@ak.com";"0123456"
"kb";"kb@kb.com";"98543221"
"akkk";"akkk@akkk.com";"0123456"
"kakk";"kakk@kakk.com";"98543221"
"aakk";"aakk@aakk.com";"0123456"
"kkak";"kkak@kkak.com";"98543221"
"akak";"akak@akak.com";"0123456"
"kakkk";"kakkk@kakkk.com";"98543221"
в результирующем файле должны быть все строки, кроме тех двух, что совпадают в обоих файлах.
и я бы все таки посмотрел в сторону compare-object. с ним не так сложно разобраться.
У меня есть две разные папки с xml-файлами. Одна папка (folder2) содержит обновленные и новые xml-файлы по сравнению с другой (folder1). Мне нужно знать, какие файлы в folder2 новые / обновлены по сравнению с folder1 и скопировать их в третью папку (folder3). Каков наилучший способ сделать это в PowerShell?
хорошо, я не собираюсь кодировать все это для вас (что в этом забавного? но я помогу тебе начать.
во-первых, есть два способа сделать сравнение содержимого. Ленивый / в основном правильный способ, который сравнивает длину файлов; и точный, но более сложный способ, который сравнивает хэш содержимого каждого файла.
для простоты, давайте сделаем простой способ и сравнить размер файла.
в основном, вы хотите два объекта, которые представляем исходную и целевую папки:
затем вы можете использовать Compare-Object чтобы увидеть, какие элементы отличаются.
Compare-Object $Folder1 $Folder2 -Property Name, Length
который будет перечислять для вас все, что отличается, сравнивая только имя и длину файловых объектов в каждой коллекции.
вы можете передать это в Where-Object фильтр, чтобы выбрать материал, который отличается с левой стороны.
Compare-Object $Folder1 $Folder2 -Property Name, Length | Where-Object | ForEach-Object
рекурсивный каталог Diff с использованием MD5 хеширования (сравнивает содержимое)
вот чистый PowerShell v3 + рекурсивный файл diff (без зависимостей), который вычисляет хэш MD5 для каждого содержимого файла каталогов (слева/справа). Можно дополнительно экспортировать CSV вместе с текстовым файлом сводки. По умолчанию выводит результат в stdout. Может либо отбросить rdiff.ps1 файл в ваш путь или скопировать содержимое в сценарий.
USAGE: rdiff path/to/left,path/to/right [-s path/to/summary/dir]
здесь суть. Рекомендуется использовать версию из gist, поскольку она может иметь дополнительные функции с течением времени. Не стесняйтесь, присылайте запросы.
далее к ответу @JNK, вы можете убедиться, что вы всегда работаете с файлами, а не с менее интуитивным выходом из Compare-Object . Вам просто нужно использовать -PassThru переключатель.
это, по крайней мере, означает, что вам не нужно беспокоиться о том, в какую сторону указывает стрелка SideIndicator!
кроме того, имейте в виду, что вы можете сравнить на LastWriteTime как хорошо.
пробегаем по подпапки рекурсивно немного сложнее, так как вам, вероятно, придется удалить соответствующие пути к корневым папкам из поля FullName перед сравнением списков.
вы можете сделать это, добавив новый ScriptProperty в списки Folder1 и Folder2:
затем вы должны быть в состоянии использовать RelativePath как свойство при сравнении двух объектов, а также использовать это, чтобы присоединиться к "C:\Folder3" при копировании, чтобы сохранить структуру папок в место.
Привет, сегодня хочу показать очередной простенький скрипт на PowerShell который будет сравнивать 2 списка из двух текстовых файлов, и в случае, если какие-либо элементы из одного списка отсутствуют во втором файле, эти элементы будут записаны в еще один файл.
Сразу покажу вам скрипт, чтобы не томить.
Расскажу предысторию, где этот скриптик мне понадобился. На самом деле всё банально просто. Обнаружилось, что на сервере антивируса, в списке компьютеров, где этот самый антивирус установлен на глаз – меньше компьютеров, чем в домене, при этом согласно политики антивирус должен быть установлен на всех компьютерах в домене.
В конторе, где я сейчас работаю – несколько сотен компьютеров, поэтому вручную сравнивать список компьютеров в консоли антивируса, и в домене – самоубийство. Соответственно, недолго думая было принято решение - взять список из домена, взять список из антивируса сравнить их, и тем самым выполнить задачу.
Если кто не понял, каждая новая строчка в файлах – новый элемент для сравнения.
Разберем работу этого скрипта.
В первых двух строчках мы считываем наши файлы.
Далее запускаем цикл для первого файла, где для каждой строки убираем пробелы, если они есть и переводим все символы в заглавные. Присваиваем переменной, которая будет показывать найден ли элемент значение ложь.
Внутри первого цикла запускаем еще один, где перебираем элементы из второго файла, так же каждую строчку отчищаем и переводим символы в заглавные и сравниваем каждый элемент из второго файла с текущим элементом из первого. Если элемент найден – присваиваем переменной значение истина.
После завершения второго цикла, если элемент не был найден, записываем его в строковую итоговою переменную, и повторяем процедуру для следующих элементов из первого файла.
В самом конце скрипта записываем нашу переменную с результатами в файл.
Вообще, я считаю, что подобный скрипт в хозяйстве всегда пригодится, поэтому надеюсь, что заметка оказалась вам полезной.
У меня есть два текстовых файла, и я хочу найти различия между ними с помощью Windows Powershell. Есть ли что-то похожее на инструмент сравнения Unix? Или есть другой способ, который я не рассмотрел?
Я пробовал сравнить объект, но получить этот загадочный вывод:
Я был очень удивлен, когда попытался сравнить два файла: несортированный массив чисел и тот же массив чисел после их сортировки. Нет выходных данных, несмотря на то, что файлы очень разные. Видимо, объект сравнения не учитывает порядок.Более простой способ сделать это - написать:
Diff и cat - это просто псевдонимы для Compare-Object и Get-Content в PowerShell. Это то же самое. несмотря на то, что это совпадает с принятым ответом, мне больше нравится использовать этот синтаксис Обратите внимание, что он не ведет себя как * nix diff вообще, как отмечают другие ответы здесь. И когда я использовал более сложное выражение вместо, cat я получил неправильный вывод, поэтому я присоединюсь к другим в рекомендации, чтобы избежать этого в PowerShell, если вы пришли из * nix.Или вы можете использовать команду DOS fc следующим образом (здесь показаны выходные данные обоих файлов, поэтому вам придется искать различия):
fc псевдоним командлета Format-Custom, поэтому обязательно введите команду как fc.exe . Обратите внимание, что многие утилиты DOS не поддерживают кодировку UTF-8.
Вы также можете запустить процесс CMD и запустить fc его внутри.
Это указывает PowerShell запустить процесс с помощью программы cmd, используя параметры в кавычках. В кавычках есть опция '/ c' cmd для запуска команды и завершения. Фактическая команда, запускаемая cmd в процессе, fc filea.txt fileb.txt перенаправляет вывод в файл diff.txt .
Вы можете использовать DOS fc.exe из PowerShell.
«fc» не работал для меня, и я не осознавал, что должен был указать его как «fc.exe», чтобы отличить его от Format-Custom. Именно то, что я искал. Благодарю. Может быть, я полный обыватель, но мне это кажется гораздо более полезным. Это очень хорошо решило мою проблему.diff on * nix - это не часть оболочки, а отдельное приложение.
Есть ли причина, по которой вы не можете просто использовать diff.exe под PowerShell?
Поскольку PowerShell включен сейчас, загружать и устанавливать нечего. Я только что закончил использовать git diff , потому что я уже установил его. Ни то, fc.exe ни другое не Compare-Object дало ожидаемого результата.Сравнивать объект (он же diff) является жалким, если вы ожидаете, что он будет вести себя как Unix Diff. Я попробовал diff (gc file1) (gc file2), и если строка слишком длинная, я не вижу фактического diff и, что более важно, я не могу сказать, на каком номере строки находится diff.
Когда я пытаюсь добавить -passthru, я теперь вижу разницу, но я теряю, в каком файле находится разница, и все равно не получаю номер строки.
Мой совет, не используйте PowerShell, чтобы найти различия в файлах. Как кто-то еще заметил, fc работает и работает немного лучше, чем Compare-Object, и еще лучше загружает и использует реальные инструменты, такие как эмулятор Unix, который упоминал Mikeage.
По-видимому, он также выполняет сравнение наборов (т.е. игнорирует порядок), как -SyncWindow и maxint по умолчанию. Если установить значение 0, это не будет работать так же, diff как и . И когда я передал канал в (. | select-object . ) качестве входных данных, он просто напечатал чепуху, поэтому я сдался.Как уже отмечали другие, если вы ожидаете вывод unix-y diff, то использование псевдонимов powershell сильно подведет вас. Во-первых, вы должны держать руку на деле при чтении файлов (с помощью gc / get-content). С другой стороны, индикатор разницы справа, вдали от контента - это кошмар читабельности.
Решение для тех, кто ищет вменяемый вывод:
- получить реальный diff (например, от GnuWin32)
- edit% USERPROFILE% \ Documents \ WindowsPowerShell \ Microsoft.PowerShell_profile.ps1
Аргумент -force необходим, потому что Powershell весьма ценен в этом конкретном встроенном псевдониме. Если кому-то интересно, установив GnuWin32, я также добавлю следующее в свой профиль powershell:
Главным образом потому, что Powershell не понимает аргументы, которые запускаются вместе и вводят, например, «rm -Force -Recurse» - это гораздо больше усилий, чем «rm -rf».
У Powershell есть несколько приятных функций, но есть некоторые вещи, которые он не должен делать для меня.
WinMerge - еще один хороший инструмент сравнения на основе графического интерфейса.
Это то, как я делал это в прошлом, это ручной процесс, который я хотел заменить небольшим скриптом.Есть также Windiff, который предоставляет интерфейс с графическим интерфейсом (отлично подходит для использования с программами CVS / SVN на основе GUI)
fc.exe лучше для сравнения текста, так как он предназначен для работы подобно * nix diff, то есть сравнивает строки последовательно, показывая реальные различия и пытаясь выполнить повторную синхронизацию (если разные секции имеют разную длину). Он также имеет несколько полезных опций управления (текстовый / двоичный, чувствительность к регистру, номера строк, длина ресинхронизации, размер буфера несоответствия) и обеспечивает состояние выхода (-1 неправильный синтаксис, 0 файлов одинаковы, 1 файл отличается, 2 файла отсутствуют). Будучи (очень) старой утилитой DOS, она имеет несколько ограничений. В частности, он не работает автоматически с Unicode, обрабатывая 0 MSB символов ASCII как терминатор строки, поэтому файл становится последовательностью из 1 строки символов (@kennycoc: используйте параметр / U, чтобы указать, что ОБА файлы являются Unicode, WinXP и далее ) и он также имеет размер буфера жесткой строки 128 символов (128 байтов ASCII,
объект сравнения предназначен для определения того, являются ли 2 объекта идентичными по элементам. если объекты являются коллекциями, то они обрабатываются как SETS (см. справочный объект сравнения), т. е. коллекции UNORDERED без дубликатов. 2 набора равны, если они имеют одинаковые элементы, независимо от порядка или дублирования. Это сильно ограничивает его полезность для сравнения текстовых файлов на предмет различий. Во-первых, поведение по умолчанию собирает различия до тех пор, пока не будет проверен весь объект (файл = массив строк), что приведет к потере информации, касающейся положения различий, и сокрытию различий между парами (и не существует понятия номера строки для SET строк). Использование -synchwindow 0 приведет к тому, что различия будут генерироваться по мере их возникновения, но не будет пытаться выполнить повторную синхронизацию, поэтому, если в одном файле есть лишняя строка, последующие сравнения строк могут завершиться неудачей, даже если файлы в противном случае идентичны (до тех пор, пока не будет получена компенсация). дополнительная строка в другом файле, таким образом выравнивая совпадающие строки). Тем не менее, PowerShell является чрезвычайно универсальным и полезное сравнение файлов может быть сделано с помощью этой функции, хотя и за счет существенной сложности и с некоторыми ограничениями на содержание файлов. Если вам нужно сравнить текстовые файлы с длинными (> 127 символов) строками и где строки в основном совпадают с 1:
где хх - длина самой длинной строки + 9
объяснение
- (gc file | % -begin < $ln=0 >-process < '<<:' -f ++$ln,$_ >) получает содержимое файла и добавляет номер строки и указатель файла (<< или >>) к каждой строке (используя оператор строки формата) перед передачей его в diff.
- -property < $_.substring(9) >сообщает diff для сравнения каждой пары объектов (строк), игнорируя первые 9 символов (которые являются номером строки и индикатором файла). При этом используется возможность указать вычисляемое свойство (значение блока скрипта) вместо имени свойства.
- -passthru заставляет diff выводить разные входные объекты (которые включают номер строки и индикатор файла) вместо отличающихся сравниваемых объектов (которые этого не делают).
- sort-object затем помещает все строки обратно в последовательность.
out-string останавливает усечение по умолчанию для вывода в соответствии с шириной экрана (как отметил Марк Тауэрсап), указав достаточно большую ширину, чтобы избежать усечения. Обычно этот вывод помещается в файл, который затем просматривается с помощью прокручиваемого редактора (например, блокнота).
Запись
Формат номера строки дает выравниваемый справа пробел номер строки из 6 символов (для сортировки). Если файлы имеют более 999 999 строк, просто измените формат на более широкий. Это также требует изменения $_.substring параметра (на 3 больше ширины номера строки) и внешнего значения xx (максимальная длина строки + $_.substring параметр).
Читайте также: