将PowerShell空间分隔输出解析为表

将PowerShell空间分隔输出解析为表,powershell,Powershell,PowerShell在运行命令时返回此输出: Mod Ports Module-Type Model Status --- ----- ----------- ------------------ ---------- 1 48 2/4/8/10/16 Gbps Advanced FC Module DS-X9448-768K9 ok 2

PowerShell在运行命令时返回此输出:

Mod Ports Module-Type Model Status --- ----- ----------- ------------------ ---------- 1 48 2/4/8/10/16 Gbps Advanced FC Module DS-X9448-768K9 ok 2 48 2/4/8/10/16 Gbps Advanced FC Module DS-X9448-768K9 ok 3 0 Supervisor Module-3 DS-X97-SF1-K9 ha-standby 4 0 Supervisor Module-3 DS-X97-SF1-K9 active *


这给出了所创建数组的行和长度,前两行是长度为5的数组,第三行和第四行有9项,因为
ModuleType中有空格

建议在PowerShell中处理此类输入的方法是将其解析为自定义对象。您可以使用正则表达式执行此操作:

$RS | Where-Object {
    $_ -match '(\d+)\s+(\d+)\s+(.*?)\s+([a-z]+(?:-[a-z0-9]+){2,})\s+(.*)'
} | ForEach-Object {
    New-Object -Type PSObject -Property @{
        'Mod'        = [int]$matches[1]
        'Ports'      = [int]$matches[2]
        'ModuleType' = $matches[3]
        'Model'      = $matches[4]
        'Status'     = $matches[5]
    }
}
或者(如果列的宽度固定),通过在定义的偏移处提取子字符串:

$RS | Select-Object -Skip 2 | ForEach-Object {
    New-Object -Type PSObject -Property @{
        'Mod'        = [int]$_.Substring(0, 3).Trim()
        'Ports'      = [int]$_.Substring(5, 5).Trim()
        'ModuleType' = $_.Substring(12, 35).Trim()
        'Model'      = $_.Substring(48, 18).Trim()
        'Status'     = $_.Substring(67).Trim()
    }
}
跳过2个标题行需要
选择对象-跳过2


如果通过
-split'\s\s+'
将所有列分隔为多个空格分隔(以两个或多个连续空格字符分隔)也可以使用。但是,对于您的数据,情况并非如此,因为至少前2个数据行在第3列和第4列之间只有一个空格。

大多数PowerShell编剧可能会说,使用任何类似于
格式表
输出的文本表作为输入是不明智的,但我喜欢挑战这一点,因为格式化的源表可以被人类读取,如果人类能够读取它们并确定(例如)列的开始和结束位置的布局,那么程序也应该能够这样做

在某些情况下(例如,对于站点的样本数据),它甚至可能比其他格式更方便,如
CSV
(难以读取且仅支持字符串数据)、
XML
(非常冗长,因此也很难读取)或
JSON
(或者,对于复杂的数据,哪一个更好,但对于包含简单本机属性的对象列表,哪一个更好)

基于这一思想,我编写了一个可重用的文档,可从PowerShell Gallery下载,并从存储库下载源代码

在您的例子中,将表转换为对象的命令非常简单,如
$RS | convertfromsourcetable
,让我演示一下:

$RS = '
    Mod Ports Module-Type                        Model              Status
    --- ----- ---------------------------------- ------------------ -----------
    1   48    2/4/8/10/16 Gbps Advance FC Module DS-X9448-768K9     ok
    2   48    2/4/8/10/16 Gbps Advance FC Module DS-X9448-768K9     ok
    3   0     Supervisor Module-3                DS-X97-SF1-K9      ha-standby
    4   0     Supervisor Module-3                DS-X97-SF1-K9      active *
'

$RS | ConvertFrom-SourceTable

Status      : ok
Model       : DS-X9448-768K9
Ports       : 48
Mod         : 1
Module-Type : 2/4/8/10/16 Gbps Advance FC Module

Mod         : 2
Module-Type : 2/4/8/10/16 Gbps Advance FC Module
Ports       : 48
Model       : DS-X9448-768K9
Status      : ok

Mod         : 3
Module-Type : Supervisor Module-3
Ports       : 0
Model       : DS-X97-SF1-K9
Status      : ha-standby

Mod         : 4
Module-Type : Supervisor Module-3
Ports       : 0
Model       : DS-X97-SF1-K9
Status      : active *
由于您的所有数据都是左对齐的(并且每一列都需要一个标题),因此可以从一开始就确定列布局,这意味着您甚至可以通过管道将此表输入流化(假定
\Plink
分别输出每一行):

.\Plink server@puttysession -pw "password" "command" | ConvertFrom-SourceTable
(这意味着如果将源表作为多行字符串提供,则
ConvertFrom-SourceTable
cmdlet将确定整个表上的列开关,否则它将基于标题、过去和当前记录)

如果源表具有更好的格式约定,例如“非字符串数据(需要解释的数据)是右对齐的”(正如
格式表
实际所做的那样)。您可以假设
Mod
端口
是整数。例如:

$Object = ConvertFrom-SourceTable '
    Mod Ports Module-Type                        Model          Status
    --- ----- -----------                        -----          ------
      1    48 2/4/8/10/16 Gbps Advance FC Module DS-X9448-768K9 ok
      2    48 2/4/8/10/16 Gbps Advance FC Module DS-X9448-768K9 ok
      3     0 Supervisor Module-3                DS-X97-SF1-K9  ha-standby
      4     0 Supervisor Module-3                DS-X97-SF1-K9  ha-standby
'
(注意,在本例中,
$Object | Format Table
将给出与输入相同的输出)


有关更多示例,请使用帮助:
help ConvertFrom SourceTable-Full

如果您可以为脚本提供文本格式的输出,这将非常有用。请不要粘贴指向屏幕截图的链接。使用正确的代码格式,并将相关文本粘贴到您的问题中。根据输出,您似乎没有取回对象,b但是,您可以使用顶行定义列名,第二行确定每列的宽度,然后使用SubString()解析其他行。这非常有效!非常感谢,还有一个问题,$match如何拆分表达式?通过使用正则表达式捕获组?是。
$matches[0]
是完全匹配的,0以上的索引是捕获组。我很高兴你不是“大多数Powershell编写者”之一,这很好。
$Object = ConvertFrom-SourceTable '
    Mod Ports Module-Type                        Model          Status
    --- ----- -----------                        -----          ------
      1    48 2/4/8/10/16 Gbps Advance FC Module DS-X9448-768K9 ok
      2    48 2/4/8/10/16 Gbps Advance FC Module DS-X9448-768K9 ok
      3     0 Supervisor Module-3                DS-X97-SF1-K9  ha-standby
      4     0 Supervisor Module-3                DS-X97-SF1-K9  ha-standby
'