我试图输入compare-object的输出。我是Powershell的新手,不幸的是还不知道这些细节。
我的命令如下:
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
我的compare-object结果如下:
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 :(得分:0)
注意:下面的代码是将纯文本数据解析为对象的练习,以实现更强大,更灵活的处理。
但是,理想情况下,处理应以对象而不是纯文本开始,
这就是从 PowerShell cmdlet 开始的原因,例如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]
个实例,带有字符串属性.SideIndicator
指示当前行(可通过.InputObject
访问)是否对LHS(第一个输入文件) - <=
- 或RHS(第二个输入文件) - {{{ 1}} 转换为自定义对象:
为每个输入对象(表示为>=
)执行传递给{ ... }
的脚本块(ForEach-Object
)。
$_
通过空格运行将“差异线”拆分为字段,并将结果字段存储为-split $_.InputObject
中的数组。
$vals
是一个辅助哈希表,用于将字段值映射到字段名称。
$ht
添加一个布尔条目,以指示手边的差异线是否来自“之前的文件”(第一个输入文件)。
$ht.Before
转换辅助。哈希表进入自定义对象并输出(通过管道发送)。
分组:
[pscustomobject] $ht
用于通过共享Group-Object
和Server
属性值对结果对象进行分组,从而生成代表每个分组的Service
实例。转换为组合自定义对象:
同样,[Microsoft.PowerShell.Commands.GroupInfo]
用于执行每个输入对象的处理。
ForEach-Object
用于构建每个组合输出对象,同样使用辅助哈希表。
[pscustomobject] @{ ... }
包含构成每个组的输入对象 - 在我们的示例中,$_.Group
和$_.Group[0]
是表示给定服务器服务的转换为对象的输入行组合
根据定义,两个输入对象都具有相同的$_.Group[1]
和.Server
值,因此盲目地使用组合输出对象的.Service
值将会这样做。
相比之下,$_.Group[0]
和* Before
属性是相应的输入对象(无论是来自第一个还是第二个文件),这就是数组索引* After
和{{通过之前添加的$ndxBefore
属性
排序:
$ndxAfter
按指定的属性对结果对象进行排序。输出格式:
.Before
可确保已排序的对象显示为表。