Powershell 比较对象输出每项 1 行
Powershell compare-object output 1 line per item
我正在尝试放置比较对象的输出。我是 Powershell 的新手,不幸的是还不知道来龙去脉。
我的命令如下:
Compare-Object -referenceObject $(Get-Content "c:\temp\mek3-first.txt") -differenceObject $(Get-Content "c:\temp\mek3-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
注意:下面的代码是将纯文本数据解析为对象以实现更健壮、灵活处理的练习。
然而,理想情况下,处理应该从对象而不是纯文本开始,
这就是为什么 从 PowerShell cmdlets 开始,例如 Get-Service
而不是 外部实用程序 的文本输出更可取。
假设每个输入文件中的所有条目在相应的其他文件中都有一个匹配的服务器+服务名称条目:
$f1, $f2 = "c:\temp\mek3-first.txt", "c:\temp\mek3-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
应用之前-returnsobjects具有单独的属性,因此您可以输出到各种格式的文件,例如使用 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(第二个输入文件)- >=
转换为自定义对象:
传递给ForEach-Object
的脚本块({ ... }
)针对每个输入对象(表示为$_
)执行。
-split $_.InputObject
通过空格将手头的 "difference line" 拆分为字段,并将结果字段作为数组存储在 $vals
.
中
$ht
是一个辅助哈希table,用于将字段值映射到字段名称。
$ht.Before
添加一个布尔值条目以指示手头的差异行是否来自 "before file"(第一个输入文件)。
[pscustomobject] $ht
转换辅助。 hashtable 到自定义 object 中并输出(通过管道发送)。
分组:
Group-Object
用于通过共享 Server
和 Service
属性 值对生成的对象进行分组,从而产生一个 [Microsoft.PowerShell.Commands.GroupInfo]
实例来表示每个分组.
转换为组合自定义对象:
同样,ForEach-Object
用于执行每个输入对象处理。
[pscustomobject] @{ ... }
用于构造每个组合输出对象,再次使用辅助散列table.
$_.Group
包含形成每个组的输入对象 - 在我们的例子中,$_.Group[0]
和 $_.Group[1]
是表示一个转换为对象的输入行给定服务器服务组合。
根据定义,两个输入对象具有相同的 .Server
和 .Service
值,因此盲目地使用 $_.Group[0]
的组合输出对象的值就可以了.
相比之下,* Before
和 * After
属性是适当的输入对象(无论是来自第一个文件还是第二个文件),这就是为什么数组索引 $ndxBefore
和 $ndxAfter
被相应地选择,通过先前添加的 .Before
属性
排序:
Sort-Object
按指定的属性对生成的对象进行排序。
输出格式:
- 输出格式化 cmdlet
Format-Table
确保排序的对象显示为 table.
我正在尝试放置比较对象的输出。我是 Powershell 的新手,不幸的是还不知道来龙去脉。
我的命令如下:
Compare-Object -referenceObject $(Get-Content "c:\temp\mek3-first.txt") -differenceObject $(Get-Content "c:\temp\mek3-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
注意:下面的代码是将纯文本数据解析为对象以实现更健壮、灵活处理的练习。
然而,理想情况下,处理应该从对象而不是纯文本开始,
这就是为什么 从 PowerShell cmdlets 开始,例如 Get-Service
而不是 外部实用程序 的文本输出更可取。
假设每个输入文件中的所有条目在相应的其他文件中都有一个匹配的服务器+服务名称条目:
$f1, $f2 = "c:\temp\mek3-first.txt", "c:\temp\mek3-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
应用之前-returnsobjects具有单独的属性,因此您可以输出到各种格式的文件,例如使用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(第二个输入文件)->=
转换为自定义对象:
传递给
ForEach-Object
的脚本块({ ... }
)针对每个输入对象(表示为$_
)执行。
中-split $_.InputObject
通过空格将手头的 "difference line" 拆分为字段,并将结果字段作为数组存储在$vals
.$ht
是一个辅助哈希table,用于将字段值映射到字段名称。$ht.Before
添加一个布尔值条目以指示手头的差异行是否来自 "before file"(第一个输入文件)。[pscustomobject] $ht
转换辅助。 hashtable 到自定义 object 中并输出(通过管道发送)。
分组:
Group-Object
用于通过共享Server
和Service
属性 值对生成的对象进行分组,从而产生一个[Microsoft.PowerShell.Commands.GroupInfo]
实例来表示每个分组.
转换为组合自定义对象:
同样,
ForEach-Object
用于执行每个输入对象处理。[pscustomobject] @{ ... }
用于构造每个组合输出对象,再次使用辅助散列table.$_.Group
包含形成每个组的输入对象 - 在我们的例子中,$_.Group[0]
和$_.Group[1]
是表示一个转换为对象的输入行给定服务器服务组合。根据定义,两个输入对象具有相同的
.Server
和.Service
值,因此盲目地使用$_.Group[0]
的组合输出对象的值就可以了.相比之下,
* Before
和* After
属性是适当的输入对象(无论是来自第一个文件还是第二个文件),这就是为什么数组索引$ndxBefore
和$ndxAfter
被相应地选择,通过先前添加的.Before
属性
排序:
Sort-Object
按指定的属性对生成的对象进行排序。
输出格式:
- 输出格式化 cmdlet
Format-Table
确保排序的对象显示为 table.
- 输出格式化 cmdlet