Как сравнить два текстовых файла в Power-Shell и отправить различия по электронной почте - PullRequest
0 голосов
/ 24 мая 2018

У меня есть 2 текстовых файла, которые содержат список имен функций SQL.Я хочу иметь возможность сравнить список в $ A и $ B.Затем я хочу, чтобы список имен функций SQL в $ B, а не в $ A, то есть список $ C, отправлялся в качестве вложения к адресу электронной почты.

Вот мой код:

   $A = "c:\ReferenceFunctions.txt"
   $B = "c:\GeneratedFunctions.txt"
   $C = "c:\FileWithDifferences.txt"


    $fromaddress = "noreply@xyz"
    $toaddress = "123@hhh"
    $bccaddress = "3333@nnn.com"
    $login = "yourlogin"
    $password = "password" | Convertto-SecureString -AsPlainText -Force
    $smtpserver = "gggg.com" 
    $smtp = new-object Net.Mail.SmtpClient($smtpserver, 800)
    $smtp.EnableSsl = $true
    $smtp.Credentials = New-Object System.Net.NetworkCredential($login, 
    $password);
    $body = "see attached "
    $Subject = "checking differences"
    $message = new-object System.Net.Mail.MailMessage
    $message.From = $fromaddress
    $message.To.Add($toaddress)
    #$message.CC.Add($CCaddress)
    $message.Bcc.Add($bccaddress)
    $message.IsBodyHtml = $True
    $message.Subject = $Subject

    $message.body = $body
    $message.Priority = [System.Net.Mail.MailPriority]::High

Compare-object (Get-Content $A) (Get-Content $B) | Out-File  $C

#Attach the eported file with differences
$attachment = $C
$attach = new-object Net.Mail.Attachment($attachment)
$message.Attachments.Add($attach)

IF (Compare-Object -ReferenceObject (Get-Content $A) -DifferenceObject (Get-Content $B)){


    $smtp.Send($message);
} 

Переменная $ A имеет следующую информацию:

fn_StatementEndOfMonth                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
fn_Performance_Sql                                                                                                                                                                                     
fn_DailyReturns 

Переменная $ B содержит следующую информацию:

fn_Performance_Sql                                                                                                                                                                                     
fn_DailyReturns 
fn_SQLPerfomance_Monitor

$ C должен содержать

fn_SQLPerfomance_Monitor

Проблема этого кода в том, что он отправляет вложение со всеми именами функций SQL в файлах $ A и $ B вместо разницы.Я не могу понять, где я иду не так.Любой, кто может помочь, пожалуйста?Пыталась выяснить весь день, но не повезло.

Ответы [ 4 ]

0 голосов
/ 24 мая 2018

В следующем фрагменте кода показано, как работает командлет Compare-Object и значение свойства SideIndicator:

$a = @'
fn_StatementEndOfMonth
fn_Performance_Sql
fn_DailyReturns
'@ -split [environment]::NewLine               ### ReferenceFunctions
$b = @'
fn_Performance_Sql
fn_DailyReturns
fn_SQLPerfomance_Monitor
'@ -split [environment]::NewLine               ### GeneratedFunctions

[environment]::NewLine                         ### for better output readability
'Compare-Object $a $b'
Compare-Object $a $b
[environment]::NewLine
'Compare-Object $a $b | ? SideIndicator -ne ''<='''
Compare-Object -ReferenceObject $a -DifferenceObject $b| 
    Where-Object { $_.SideIndicator -ne '<=' }
[environment]::NewLine
'Compare-Object $a $b | ? SideIndicator -ne ''=>'''
Compare-Object -ReferenceObject $a -DifferenceObject $b | 
    Where-Object { $_.SideIndicator -ne '=>' }
[environment]::NewLine
'Compare-Object $a $b -PassThru'
Compare-Object $a $b -PassThru
[environment]::NewLine
'Compare-Object $a $b -PassThru | ? SideIndicator -ne ''<='''
Compare-Object -ReferenceObject $a -DifferenceObject $b -PassThru | 
    Where-Object { $_.SideIndicator -ne '<=' }
[environment]::NewLine
'Compare-Object $a $b -PassThru | ? SideIndicator -ne ''=>'''
Compare-Object -ReferenceObject $a -DifferenceObject $b -PassThru | 
    Where-Object { $_.SideIndicator -ne '=>' }

Вывод :

PS D:\PShell> D:\PShell\SO\50510142.ps1

Compare-Object $a $b

InputObject              SideIndicator
-----------              -------------
fn_SQLPerfomance_Monitor =>           
fn_StatementEndOfMonth   <=           

Compare-Object $a $b | ? SideIndicator -ne '<='
fn_SQLPerfomance_Monitor =>           

Compare-Object $a $b | ? SideIndicator -ne '=>'
fn_StatementEndOfMonth   <=           

Compare-Object $a $b -PassThru
fn_SQLPerfomance_Monitor
fn_StatementEndOfMonth

Compare-Object $a $b -PassThru | ? SideIndicator -ne '<='
fn_SQLPerfomance_Monitor

Compare-Object $a $b -PassThru | ? SideIndicator -ne '=>'
fn_StatementEndOfMonth

Дляте, кто запутался в выводе Compare-Object:

$x = Compare-Object $a $b
$x[0].Gettype()
$y = Compare-Object $a $b -PassThru
$y[0].Gettype()
IsPublic IsSerial Name                                     BaseType            
-------- -------- ----                                     --------            
True     False    PSCustomObject                           System.Object       
True     True     String                                   System.Object       

Выше действителен, несмотря на документация (ошибочно) говорит

Выходы

Нет или объекты, которые отличаются.

При использовании параметра PassThru, Compare-Object возвращает объекты, которые отличались.В противном случае этот командлет не создает никаких выходных данных .

0 голосов
/ 24 мая 2018

Кажется, что вы действительно хотите сделать полную противоположность объекту сравнения.Чтобы получить именно то, что вы сказали, что вам нужно в $ C (я не уверен, почему 'fn_StatementEndOfMonth' также не должно быть там), вы можете сделать следующее:

$a = 'fn_StatementEndOfMonth
fn_Performance_Sql
fn_DailyReturns' -split '[\r\n]'

$b = 'fn_Performance_Sql
fn_DailyReturns
fn_SQLPerfomance_Monitor' -split '[\r\n]'

$c = $b | % { if($_ -notin $a){$_} }

$c

fn_SQLPerfomance_Monitor

0 голосов
/ 24 мая 2018

Вы должны отфильтровать объекты разности, которые Compare-Object выводит, по их .SideIndicator свойству , чтобы получить только элементы, уникальные для данной стороны (синтаксис PSv3 +):

Compare-Object (Get-Content $A) (Get-Content $B) -PassThru | 
  Where-Object Sideindicator -eq '=>' | 
    Out-File $C
  • Where-Object Sideindicator -eq '=>' выводит только те разностные объекты , представляющие элементы, которые являются уникальными для вправо сторона (т. е. аргумент second , в данном случае строки файла $B).

    • Различным объектом является экземпляр [pscustomobject], представляющий одну разницу междувходные коллекции.Он имеет два свойства:
      • .SideIndicator содержит стрелку (строку), указывающую на сторону, для которой входной объект уникален: <= или =>;если вы используете переключатель -IncludeEqual, объекты, представленные в , обе коллекции представлены с ==
      • .InputObject, представляющими входной объект под рукой.
  • -PassThru приводит к Compare-Object выводу входных объектов самих вместо обычных разностных объектов:

    • Это позволяетотправить строки в выходной файл;без -PassThru, Out-File записывает объекты разности в целом, что приводит к табличному представлению;вам нужно получить доступ к свойству .InputObject, чтобы получить только строку.
    • Однако свойство .SideIndicator все еще присутствует, поскольку PowerShell добавляет элемент NoteProperty с таким именем к каждому объекту.таким образом, фильтр Where-Object по-прежнему работает как задумано.
0 голосов
/ 24 мая 2018

Вам не хватает -PassThru переключатель команды Compare-Object:

$A = Get-Content 'C:\temp\test1.txt'
$B = Get-Content 'C:\temp\test2.txt'
$C = 'c:\temp\diff.txt'

Compare-Object $A $B -PassThru | Out-File -FilePath $C
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...