$Text = @'
@SUB-SECTOR: sec_C SECTOR: reft
#
# Trade routes within the subsector
#
#--------1---------2---------3---------4---------5---------6---
#PlanetName Loc. UPP Code B Notes Z PBG Al LRX *
#---------- ---- --------- - --------------- - --- -- --- -
Lemente 1907 B897563-B Ag Ni 824 Na
Zamoran 2108 B674675-A Q Ag Ni 904 Dr
'@
您可以使用原始here string 作为ConvertFrom-SourceTable cmdlet 的输入,但如果使用Get-Content 从文件中检索数据,$Table 可能是一个字符串数组(行):
$Table = $Text -Split "[\r\n]+"
如果您的标题从不改变,最简单的方法是使用-Header 和-Ruler 参数重新定义标题行和标尺:
$Table | Select -Skip 7 | ConvertFrom-SourceTable `
-Header 'PlanetName Loc. UPP Code B Notes Z PBG Al LRX *' `
-Ruler '---------- ---- --------- - --------------- - --- -- --- -' `
| Format-Table
PlanetName Loc. UPP Code B Notes Z PBG Al LRX *
---------- ---- -------- - ----- - --- -- --- -
Lemente 1907 B897563-B Ag Ni 824 Na
Zamoran 2108 B674675-A Q Ag Ni 904 Dr
(顺便说一句。-Ruler 参数在这里并不是真正需要的,可以在此特定表中省略)
如果每个表格的标题都不同,您可能会考虑自动重新格式化表格,并从标题和标尺行中删除 # 并将其替换为空格:
$Table | Select -Skip 5 |
ForEach-Object {$_ -Replace '^#', ' '} |
ConvertFrom-SourceTable | Format-Table
第一列未完全正确对齐,但随后的数据将对其进行校正。有一个例外:特别是当输入是在流中提供时[1],与标头/标尺右对齐的数据(通常是整数,如下例所示)将是 默认由ConvertFrom-SourceTable cmdlet 解释。
[1] 如果输入作为管道流(而不是此处的原始字符串)提供,ConvertFrom-SourceTable cmdlet 将充当in the middle of a pipeline cmdlet,并为下一个 cmdlet 中间释放每个对象。因此,它将只能确定列连接和调整到当前行。
ConvertFrom-SourceTable '
PlanetName Loc. UPP Code B Notes Z PBG Al LRX *
---------- ---- -------- - ----- - --- -- --- -
12345789012 1907 B897563-B Ag Ni 824 Na
123 2108 B674675-A Q Ag Ni 904 Dr
' | Format-Table
(这里注意上面表格输入和Format-Table输出完全一样)
也就是说,如果第一行第一列的字段是一个与表头右对齐的字符串(如上例中的12个字符),如果无法解释就会产生错误(例如,如果它不是数字)。您可以使用-Literal 开关避免这种情况。
结论
我猜这个命令将使用ConvertFrom-SourceTable cmdlet 完成整个技巧:
$Table | Select -Skip 5 |
ForEach-Object {$_ -Replace '^#', ' '} |
ConvertFrom-SourceTable -Literal | Format-Table
更新(2019 年 5 月 3 日)
我在ConvertFrom-SourceTable 中添加了一项新功能,该功能可能会用于像这样的浮动表格:
-Floating
默认情况下,浮动表格中的介绍带有不带标尺的标尺
通过管道流式传输的内容会自动跳过。
如果为管道输入提供了-Floating 开关,则
对象的流式传输将从标尺开始(流式浮动表
不能没有尺子)。
如果浮动被显式禁用 (-Floating:$False),则标头
假定在第一行,即使表格没有流式传输。
这意味着您可以将命令简化为并且不必再将-Skip 指定到某一行:
ConvertFrom-SourceTable -Literal ($Table | ForEach-Object {$_ -Replace '^#', ' '})
如果您想从(大)输入文件流式传输数据,则需要提供-Floating 开关来告诉 cmdlet 等待标尺:
$Table | ForEach-Object {$_ -Replace '^#', ' '} |
ConvertFrom-SourceTable -Literal | Format-Table
更新(2019 年 10 月 6 日)
我已更新 ConvertFrom-SourceTable cmdlet。
虽然-Markdown 和-Floating 参数已经用尽,但cmdlet 仍然支持markdown 和浮动表。这些功能可以通过显式设置
-HorizontalDash(别名-HDash)和-VerticalDash(别名-VDash)参数来实施
(见Help -Full ConvertFrom-SourceTable。
对于这个特定的问题:
如果它涉及原始表(完整的文本表,行由换行符分隔):
PS C:\> ConvertFrom-SourceTable ($Text -Replace '#', ' ') | Format-Table
PlanetName Loc. UPP Code B Notes Z PBG Al LRX *
---------- ---- -------- - ----- - --- -- --- -
Lemente 1907 B897563-B Ag Ni 824 Na
Zamoran 2108 B674675-A Q Ag Ni 904 Dr
如果您喜欢流式传输输入(和输出),则需要通过显式设置水平破折号字符 (-Hash '-') 来定义表格的开始位置:
PS C:\> $Text -Split "[\r\n]+" | ForEach-Object {$_ -Replace '^#', ' '} |
ConvertFrom-SourceTable -HDash '-' | Format-Table
PlanetName Loc. UPP Code B Notes Z PBG Al LRX *
---------- ---- -------- - ----- - --- -- --- -
Lemente 1907 B897563-B Ag Ni 824 Na
Zamoran 2108 B674675-A Q Ag Ni 904 Dr