2017-06-16 34 views
1

我试图把比较对象的输出。我是Powershell的新手,不幸的是,还不知道这些情况。Powershell比较对象输出每行1行

我的命令如下:是

Compare-Object -referenceObject $(Get-Content "c:\temp\mek\123-first.txt") -differenceObject $(Get-Content "c:\temp\mek\123-second.txt") | %{$_.Inputobject} | sort-object | out-file "c:\temp\mek\results.txt" 

我的文件内容如下(简单地比较的Windows服务):

 
systemname name           state startmode 
---------- ----           ----- --------- 
D7MCYP  AdobeARMservice        Stopped Auto  
D7MCYP  AdobeFlashPlayerUpdateSvc     Stopped Manual 
D7MCYP  AeLookupSvc         Stopped Manual 

我的比较对象的结果如下:

 
BL3C4V  wudfsvc          Stopped Auto 
BL3C4V  wudfsvc          Stopped Manual 
D7MCYP  AdobeARMservice        Running Auto  
D7MCYP  AdobeARMservice        Stopped Auto  

现在,如果有人可以帮助输出保持每台服务器的前2列和差异列3,4的新值到新列(5,6)。如果我也可以获得标题,这也会很好。例如:

 
Server  Service    Before State Before Mode  After State After Mode 
BL3C4V  wudfsvc    Stopped   Auto   Stopped   Manual 
D7MCYP  AdobeARMservice  Running   Auto   Stopped   Auto  
+0

其你wicj构建文件?你可以用csv吗? – Esperento57

+0

我不确定“wicj build file”是什么意思......不,我不使用CSV,而是将数据导出到普通的旧txt文件。 –

回答

0

注:下面的代码是在解析纯文本数据转换为对象进行更强大的,灵活的处理的练习。
理想情况下,然而,加工应开始时与对象,而不是纯文本, 这就是为什么开始PowerShell命令Get-Service,而不是从外部公用事业优选输出的文本

假设在每个输入文件中的所有条目都在相应的其他文件的匹配服务器+服务名称条目:

$f1, $f2 = "c:\temp\mek\123-first.txt", "c:\temp\mek\123-second.txt" 
Compare-Object (Get-Content $f1) (Get-Content $f2) | ForEach-Object { 
    $i = 0; $ht = @{}; $vals = -split $_.InputObject 
    foreach($col in 'Server', 'Service', 'State', 'Mode') { 
     $ht.$col = $vals[$i++] 
    } 
    $ht.Before = $_.SideIndicator -eq '<=' 
    [pscustomobject] $ht 
    } | Group-Object Server, Service | ForEach-Object { 
     $ndxBefore, $ndxAfter = if ($_.Before) { 0, 1 } else { 1, 0 } 
     [pscustomobject] @{ 
     Server = $_.Group[0].Server 
     Service = $_.Group[0].Service 
     'State Before' = $_.Group[$ndxBefore].State 
     'Mode Before' = $_.Group[$ndxBefore].Mode 
     'State After' = $_.Group[$ndxAfter].State 
     'Mode After' = $_.Group[$ndxAfter].Mode 
     } 
    } | Sort-Object Server, Service | 
     Format-Table 

注:

  • 上述格式的输出用于显示(使用Format-Table),而不发送到文件。
    您可以附加| Out-File "c:\temp\mek\results.txt"将相同的表示保存到文件。

  • 但是,请注意,命令 - Format-Table之前应用 - 返回对象有个别属性,这样你就可以输出到各种格式,文件如通过使用Export-Csv,例如。

输出示例:

Server Service     State Before Mode Before State After Mode After 
------ -------     ------------ ----------- ----------- ---------- 
D7MCYP AdobeFlashPlayerUpdateSvc Stopped  Manual  Stopped  Auto  
D7MCYP AeLookupSvc    Stopped  Manual  Started  Manual  

说明

一个单一的,长的管道被使用,其使得代码简洁和内存效率。
管道分解如下:

  • 比较:

    • Compare-Object从由Get-Content调用所返回的两个输入文件中的行阵列进行比较,并输出表示差异[pscustomobject]实例发现,与指示手头的线(经由.InputObject访问)是否是唯一的LHS(第1输入文件)字符串属性.SideIndicator - <= - 或第ÈRHS(第二输入文件) - >=
  • 转变到定制对象:

    • { ... })传递给ForEach-Object脚本程序块是对每一输入对象(表示为$_)执行。

    • -split $_.InputObject通过运行空白将手头的“差异线”分割成字段,并将结果字段作为数组存储在$vals中。

    • $ht是一个辅助散列表,用于将字段值映射到字段名称。

    • $ht.Before增加了一个布尔表项来指示当前差异线是否来自“之前的文件”(第一个输入文件)。

    • [pscustomobject] $ht转换的辅助。散列表到自定义对象并输出它(通过管道发送它)。

  • 分组:

    • Group-Object用于组所得到的目的可以通过共享ServerService属性值,产生表示每个分组一个[Microsoft.PowerShell.Commands.GroupInfo]实例。
  • 变换到组合自定义对象:

    • 同样,ForEach-Object用于执行每个输入对象的处理。

    • [pscustomobject] @{ ... }用于构造每个组合的输出对象,同样使用辅助散列表。

    • $_.Group包含形成每个组中的输入对象 - 在我们的情况下,$_.Group[0]$_.Group[1]是表示给定服务器的服务组合的转化至对象的输入线。

    • 根据定义,两个输入对象具有相同的.Server.Service值,所以对组合输出对象盲目使用$_.Group[0]的值将会执行。

    • 相比之下,* Before* After特性相应的输入对象(无论是从第一或第二文件),这就是为什么在数组索引$ndxBefore$ndxAfter被相应地选择,通过预先添加.Before属性

  • 排序:

    • Sort-Object排序由指定的属性所产生的对象。
  • 输出格式:

    • 输出格式化小命令Format-Table确保排序对象被呈现为