如何比较power-shell中的两个文本文件并将差异发送到电子邮件

时间:2018-05-24 13:01:14

标签: powershell

我有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

这段代码的问题在于,它发送了一个附件,其中包含文件$ A和$ B中的所有SQL函数名称,而不是差异。我似乎无法弄清楚哪里出错了。有人可以帮助吗?一直想弄清楚这一整天,但没有运气。

4 个答案:

答案 0 :(得分:1)

您必须过滤由Compare-Object属性输出.SideIndicator的差异对象,才能获得给定的唯一项方 (PSv3 +语法):

Compare-Object (Get-Content $A) (Get-Content $B) -PassThru | 
  Where-Object Sideindicator -eq '=>' | 
    Out-File $C
  • Where-Object Sideindicator -eq '=>'仅输出表示右侧侧唯一的差异对象(即第二个 >参数,在这种情况下文件行$B。)

    • 差异对象是[pscustomobject]实例,表示输入集合之间的单个差异。它有两个属性:
      • .SideIndicator包含一个箭头(字符串),指向手边的输入对象所独有的一侧:<==>;如果您使用-IncludeEqual开关,两个集合中的对象都会以==
      • 表示
      • .InputObject代表手头的输入对象。
  • -PassThru导致Compare-Object输出输入对象自己而不是通常的差异对象:

    • 这使您可以将字符串发送到输出文件;如果没有-PassThruOut-File会将差异对象整体写入,从而产生表格表示;您必须访问.InputObject属性才能获取字符串。
    • 但是,.SideIndicator属性仍然存在,因为PowerShell会为每个对象添加一个具有该名称的NoteProperty成员,因此Where-Object过滤器仍可按预期工作。

答案 1 :(得分:0)

你在比较对象命令中缺少-PassThru开关:

$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

答案 2 :(得分:0)

看起来你真的想要做与compare-object完全相反的事情。为了得到你所说的你需要的$ 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

答案 3 :(得分:0)

以下代码段显示了Compare-Object cmdlet的工作原理以及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       

尽管documentation (wrongly) says

,上述内容仍然有效
  

<强>输出

     

无,或不同的对象。

     

使用PassThru参数时,Compare-Object会返回   不同的对象。否则,此cmdlet 不会   生成任何输出