我还是Powershell的新手;并且无法绕过将字符串转换为PowerShell友好对象的方式(转换为Powershell属性名称和每个属性名称的相应值,或者,如果那太复杂,那么,二维阵列网格)。理想情况下,我不介意看每种方式是如何实现的,所以我可以在将来做任何一种方式。无论如何,这是下面的字符串:
$String =
" Port Name Status Vlan Duplex Speed Type
Fa1/0/1 Router 2 connected trunk full 100 10/100BaseTX
Fa1/0/2 User connected 101 full 100 10/100BaseTX
Fa1/0/3 User notconnect 101 full 100 10/100BaseTX
Fa1/0/4 Video VLAN connected 503 full 100 10/100BaseTX
Fa1/0/5 User notconnect 101 full 100 10/100BaseTX
"
由于我的Powershell脚本编写经验非常有限,我几乎无法只使用 [regex] :: split )来创建单维数组。不幸的是,我使用该方法的方式导致数组中的空项;而且,似乎没有像String.split那样的[StringSplitOptions]“RemoveEmptyEntries”功能。
type int.txt | %{$data = [regex]::split($_, '(\s\s)+')
Write-Output "$($data[0])`t$($data[1])`t$($data[2])`t$($data[3])`t$($data[4])`t$($data[5])`t$($data[6])`t$($data[7])"}
因此,我最终将一些不需要的空项分配给数组;输出如下:
Port Name Status
Fa1/0/1 Router 2 connected
Fa1/0/2 User connected
Fa1/0/3 User notconnect
Fa1/0/4 Video VLAN connected
Fa1/0/5 User notconnect
无论如何,我真的很想要专家的解决方案来演示如何将字符串转换为Powershell Properties和/或二维数组。提前谢谢!
答案 0 :(得分:4)
如果你正在处理固定宽度的数据,并且不一定相信你有可分割的可预测分隔符那么你可能想要纯粹基于列位置来解析它。您会看到使用string.substring()方法经常完成,但您可以使用正则表达式。就个人而言,我更喜欢正则表达式。这是一个例子:
$string =
@'
Port Name Status Vlan Duplex Speed Type
Fa1/0/1 Router 2 connected trunk full 100 10/100BaseTX
Fa1/0/2 User connected 101 full 100 10/100BaseTX
Fa1/0/3 User notconnect 101 full 100 10/100BaseTX
Fa1/0/4 Video VLAN connected 503 full 100 10/100BaseTX
Fa1/0/5 User notconnect 101 full 100 10/100BaseTX
'@
$regex = '(.{10})(.{19})(.{13})(.{11})(.{8})(.{6})(.+)'
$string.split("`n") -notmatch '\s*Port\s+' |
foreach {
if ($_.trim() -match $regex)
{ [PSCustomObject]@{
Port = $Matches[1].trim()
Name = $Matches[2].trim()
Status = $Matches[3].trim()
Vlan = $Matches[4].trim()
Duplex = $Matches[5].trim()
Speed = $Matches[6].trim()
Type = $Matches[7].trim()
}
}
} | ft -AutoSize
Port Name Status Vlan Duplex Speed Type
---- ---- ------ ---- ------ ----- ----
Fa1/0/1 Router 2 connected trunk full 100 10/100BaseTX
Fa1/0/2 User connected 101 full 100 10/100BaseTX
Fa1/0/3 User notconnect 101 full 100 10/100BaseTX
Fa1/0/4 Video VLAN connected 503 full 100 10/100BaseTX
Fa1/0/5 User notconnect 101 full 100 10/100BaseTX
答案 1 :(得分:2)
这是另一个版本,FWIW:
$regex = '(.{10})(.{19})(.{13})(.{11})(.{8})(.{6})(.+)'
$props = ',Port,Name,Status,Vlan,Duplex,Speed,Type'.split(',')
$ht = [ordered]@{}
$string.split("`n") -notmatch '\s*Port\s+' |
foreach {
if ($_.trim() -match $regex) {
for ($i=1;$i -lt $props.count;$i++)
{ $ht[$props[$i]]=$matches[$i]}
[PSCustomObject]$ht
}
}
答案 2 :(得分:0)
试试这个。
$String = @"
Port Name Status Vlan Duplex Speed Type
Fa1/0/1 Router 2 connected trunk full 100 10/100BaseTX
Fa1/0/2 User connected 101 full 100 10/100BaseTX
Fa1/0/3 User notconnect 101 full 100 10/100BaseTX
Fa1/0/4 Video VLAN connected 503 full 100 10/100BaseTX
Fa1/0/5 User notconnect 101 full 100 10/100BaseTX
"@
$temp = $string -split "`n" |
Foreach {$_ -replace '(\S+) (\S+)\s*$', '$1 $2' -replace '^\s+',''}
$temp | Foreach {$_ -replace '(?<=\S) (?=\S)',[char]0xA0 -replace ' +',' ' } |
ConvertFrom-Csv -Delimiter ' ' | Format-Table -auto
这可以通过准备输入字符串以在最后一列和最后一列之间放置两个空格然后用不间断的空格替换剩余的单个空格。
答案 3 :(得分:-1)
让我们将其转换为csv文件,然后导入它。这将为您提供一个数组,其中包含表示每个接口及其所有属性的对象。
PS > $a = Get-Content .\int.txt | Foreach {$_.Trim() -replace ' {2,}',','} | ConvertFrom-Csv
PS > $a | ft -AutoSize
Port Name Status Vlan Duplex Speed Type
---- ---- ------ ---- ------ ----------
Fa1/0/1 Router 2 connected trunk full 100 10/100BaseTX
Fa1/0/2 User connected 101 full 100 10/100BaseTX
Fa1/0/3 User notconnect 101 full 100 10/100BaseTX
Fa1/0/4 Video VLAN connected 503 full 100 10/100BaseTX
Fa1/0/5 User notconnect 101 full 100 10/100BaseTX
这也适用于界面名称中的空格,只要它们只是单词之间的单个空格。