我有一个原生CMD命令输出这个文本:每个部分用'-----'划线,我希望得到不同数组中的每个部分,所以我可以处理每个部分的结果,
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
---Processing--------------------------
---------------------------------------
SKU ID: 2b88c4f2-ea8f-43cd-805e-4d41346e18a7
LICENSE NAME: Office 15, OfficeProPlusVL_MAK edition
LICENSE DESCRIPTION: Office 15, RETAIL(MAK) channel
BETA EXPIRATION: 01/01/1601
LICENSE STATUS: ---LICENSED---
Last 5 characters of installed product key: HT7T7
---------------------------------------
SKU ID: 3e4294dd-a765-49bc-8dbd-cf8b62a4bd3d
LICENSE NAME: Office 15, OfficeVisioProVL_MAK edition
LICENSE DESCRIPTION: Office 15, RETAIL(MAK) channel
BETA EXPIRATION: 01/01/1601
LICENSE STATUS: ---LICENSED---
Last 5 characters of installed product key: WTWRR
---------------------------------------
SKU ID: ed34dc89-1c27-4ecd-8b2f-63d0f4cedc32
LICENSE NAME: Office 15, OfficeProjectProVL_MAK edition
LICENSE DESCRIPTION: Office 15, RETAIL(MAK) channel
BETA EXPIRATION: 01/01/1601
LICENSE STATUS: ---LICENSED---
Last 5 characters of installed product key: TVGWY
---------------------------------------
---------------------------------------
---Exiting-----------------------------
修改 这是我的代码,我认为它很复杂,但只是为了让你知道我不希望你这样做:
Function Parse-OSPPResult
{
Param(
[Parameter(Mandatory = $true)]
$Result
)
$c = $Result | ? {$_ -notmatch '^Microsoft|^Copyright|Processing|Exiting|^LICENSE STATUS'}
$c = $c[0..($c.Length -3)]
$LineNumbers = $c | Select-String '^--' |select -ExpandProperty linenumber
if ($LineNumbers.Count -gt 1)
{
$array = @{}
for ($i=0; $i -lt ($LineNumbers.Count -1); $i++)
{
$array[$i] = $c[$LineNumbers[$i]..($LineNumbers[($i + 1)]-2)]
}
$array[$i] = $c[$LineNumbers[$i]..($c.Length -1)]
}
else
{
$array[0] = $c[$LineNumbers..($c.Length)]
}
$arr = @()
foreach ($item in ($array.GetEnumerator() | % {$_.Name}))
{
$Name = (($array[$item] | ? {$_ -match '^LICENSE NAME:'}) -split ': ')[-1]
$Desc = (($array[$item] | ? {$_ -match '^LICENSE DESCRIPTION:'}) -split ': ')[-1]
$Key = (($array[$item] | ? {$_ -match '^Last 5'}) -split ': ')[-1]
$row = "" | Select Name,Description,Key
$row.Name = $Name
$row.Description = $Desc
$row.Key = $Key
$arr += $row
}
return $arr
}
结果:
Name Description Key
---- ----------- ---
Office 15, OfficeProjectProVL_MAK edition Office 15, RETAIL(MAK) channel HT7T7
Office 15, OfficeVisioProVL_MAK edition Office 15, RETAIL(MAK) channel WTWRR
Office 15, OfficeProPlusVL_MAK edition Office 15, RETAIL(MAK) channel TVGWY
如果可能,很乐意看到其他方法。
*注意:有时结果只有一部分......
感谢。
答案 0 :(得分:4)
我这样做:
function Split-CommandOutput
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[string[]]$InputObject
)
End
{
# Collect all pipeline input and make sure it's an array of strings
$InputObject = @($input) | ForEach-Object {$_ -split [System.Environment]::NewLine}
# Separator to split records
$Separator = '^-+$'
# Find start and end indexes of each record
$RecordBounds = 0..($InputObject.Length-1) | Where-Object {$InputObject[$_] -match $Separator}
# Split records into multidimensional array
$Records = @()
for ($i=0 ; $i -lt ($RecordBounds.Length-1) ; $i++)
{
$Records += ,($InputObject[($RecordBounds[$i]+1)..($RecordBounds[$i+1]-1)])
}
# Process each record
foreach($record in $Records)
{
# For each item in record
$Properties = @{}
foreach($item in $record)
{
# Extract data using regex
if($item -match '\s*(.+)\s*:\s*(.+)\s*')
{
$Properties.Add($Matches[1], $Matches[2])
}
}
# Create new object
New-Object -TypeName PSCustomObject -Property $Properties
}
}
}
您可以将字符串,字符串数组和工具输出直接传递给此函数:
MyTool.exe | Split-CommandOutput
$ArrayOfStrings | Split-CommandOutput
$SingleString | Split-CommandOutput
结果:
LICENSE NAME : Office 15, OfficeProPlusVL_MAK edition
LICENSE DESCRIPTION : Office 15, RETAIL(MAK) channel
BETA EXPIRATION : 01/01/1601
SKU ID : xxxxxxx-ea8f-43cd-805e-xxxxxxxxxx
LICENSE STATUS : ---LICENSED---
Last 5 characters of installed product key : XXXXX
LICENSE NAME : Office 15, OfficeVisioProVL_MAK edition
LICENSE DESCRIPTION : Office 15, RETAIL(MAK) channel
BETA EXPIRATION : 01/01/1601
SKU ID : xxxxxxx-a765-49bc-8dbd-xxxxxxxxxx
LICENSE STATUS : ---LICENSED---
Last 5 characters of installed product key : XXXXX
LICENSE NAME : Office 15, OfficeProjectProVL_MAK edition
LICENSE DESCRIPTION : Office 15, RETAIL(MAK) channel
BETA EXPIRATION : 01/01/1601
SKU ID : ed34dc89-1c27-4ecd-8b2f-63d0f4cedc32
LICENSE STATUS : ---LICENSED---
Last 5 characters of installed product key : XXXXX
答案 1 :(得分:3)
这对我有用
$text = @'
---Processing--------------------------
---------------------------------------
SKU ID: xxxxxxx-ea8f-43cd-805e-xxxxxxxxxx
LICENSE NAME: Office 15, OfficeProPlusVL_MAK edition
LICENSE DESCRIPTION: Office 15, RETAIL(MAK) channel
BETA EXPIRATION: 01/01/1601
LICENSE STATUS: ---LICENSED---
Last 5 characters of installed product key: XXXXX
---------------------------------------
SKU ID: xxxxxxx-a765-49bc-8dbd-xxxxxxxxxx
LICENSE NAME: Office 15, OfficeVisioProVL_MAK edition
LICENSE DESCRIPTION: Office 15, RETAIL(MAK) channel
BETA EXPIRATION: 01/01/1601
LICENSE STATUS: ---LICENSED---
Last 5 characters of installed product key: XXXXX
---------------------------------------
SKU ID: ed34dc89-1c27-4ecd-8b2f-63d0f4cedc32
LICENSE NAME: Office 15, OfficeProjectProVL_MAK edition
LICENSE DESCRIPTION: Office 15, RETAIL(MAK) channel
BETA EXPIRATION: 01/01/1601
LICENSE STATUS: ---LICENSED---
Last 5 characters of installed product key: XXXXX
---------------------------------------
---------------------------------------
---Exiting-----------------------------
'@ -split "`n"
$hash = @{}
$object = foreach ($line in $text) {
if ($line.startswith('----') -and [bool]$($hash.Keys)) {
[pscustomobject]$hash
$hash = @{}
continue
} elseif ($line -match '(.*):(.*)') {
$hash.Add($Matches[1].trim(), $Matches[2].trim())
}
}
$object
答案 2 :(得分:3)
更整洁的版本:
# Somewhere to hold the information for each program entry
$program = @{}
$result = foreach ($line in Get-Content d:\t.txt) {
# Reset at the beginning of a new SKU or at the end of everything.
# Output the program details, and initialize for the next one
if ($line -match '^SKU' -or $line -match '---Exiting') {
if ($program.Count) { [pscustomobject]$program }
$program = @{}
}
# Lines which have colons contain data
if ($line -match ':') {
$name, $value = $line.Split(':', 2)
# Replace the long names with the desired shorter names
switch -Regex ($name) {
'license name' { $name = 'Name' }
'license description' { $name = 'Description' }
'product key' { $name = 'Key' }
}
# Save the data for each line into the program store
$program[$name] = $value
}
}
# Choose the desired results
$result | select Name, Description, Key
高尔夫版:
(gc d:\t.txt -Raw)-split'-{39}'|%{$p=@{};($_-split'\n')-match':'|%{
$k,$v=$_.Split(':',2);$p[$k]=$v.Trim()};if($p.Count){[pscustomobject]$p}}