我有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函数名称,而不是差异。我似乎无法弄清楚哪里出错了。有人可以帮助吗?一直想弄清楚这一整天,但没有运气。
答案 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
输出输入对象自己而不是通常的差异对象:
-PassThru
,Out-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不会 生成任何输出。