首页 > 解决方案 > 将 PowerShell 空格分隔的输出解析为表格

问题描述

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

PS输出

Mod Ports 模块类型模型状态
--- ----- ------------ ------ ----------
1 48 2/4/8/10/16 Gbps 高级 FC 模块 DS-X9448-768K9 正常
2 48 2/4/8/10/16 Gbps 高级 FC 模块 DS-X9448-768K9 正常
3 0 Supervisor Module-3 DS-X97-SF1-K9 ha-standby
4 0 管理模块-3 DS-X97-SF1-K9 激活 *

我在尝试拆分它时遇到了麻烦,因为它不是制表符分隔的,是空格分隔的,因此当我使用.split("")该列时Module-Type,由于其内容也有空格,因此该列被错误地分隔。

我是新手,任何帮助将不胜感激。

这是我的代码:

$RS = .\Plink server@puttysession -pw "password" "command"

foreach ($RSln in $RS){
    $arr = $RSln.split('',[System.StringSplitOptions]::RemoveEmptyEntries)
    Write-Host $RSln "|" $arr.Length
}

这给了我创建数组的行和长度,前两行是长度为 5 的数组,第三行和第四行有 9 个项目,因为ModuleType

标签: powershell

解决方案


大多数 PowerShell 脚本编写者可能会说,使用任何类似于Format-Table输出的文本表作为输入是个坏主意,但我喜欢挑战这一点,因为格式化的源表可以被人类读取,并且人类可以读取它们并确定例如布局关于列的开始和结束位置,程序应该能够做同样的事情......

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

基于这个想法,我编写了一个可重用的ConvertFrom-SourceTablecmdlet,可在 PowerShell Gallery 下载,源代码来自GitHubiRon7/ConvertFrom-SourceTable存储库。

在您的情况下,将表转换为对象的命令很简单$RS | ConvertFrom-SourceTable,让我展示一下:

$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-SourceTablecmdlet 将确定整个表的列巫术,否则它基于标题、过去和当前记录)

如果源表具有更好的格式约定,例如“非字符串数据(需要解释的数据)是右对齐的”(实际上由 完成Format-Table)。您可以做出一个假设(就像@Ansgar Wiechers 所做的那样),Mod并且Ports整数是一个事实。例如:

$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


推荐阅读