Powershell regex split string
我还是 Powershell 的新手;并且无法将我的头转换为一种将字符串转换为对 powershell 友好的对象的方法(转换为 Powershell 属性名称和每个属性名称的相应值,或者,如果这太复杂,则转换为二维数组网格)。理想情况下,我不介意查看每种方式是如何实现的,因此我将来可以采用任何一种方式。无论如何,这是下面的字符串:
1 2 3 4 5 6 7 8 | $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" 功能。
1 2 | 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])"} |
因此,我最终将一些不需要的空项分配给数组;输出如下:
1 2 3 4 5 6 | 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 属性和/或二维数组。提前致谢!
如果您正在处理固定宽度的数据,并且不一定相信您会有可预测的分隔符来拆分,那么您可能希望纯粹基于列位置来解析它。您会看到经常使用 string.substring() 方法完成此操作,但您可以使用正则表达式。就个人而言,我更喜欢正则表达式。这是一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | $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 |
这是另一个版本,FWIW:
1 2 3 4 5 6 7 8 9 10 11 12 | $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 } } |
试试这个。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $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 |
这通过准备输入字符串来在最后一列和最后一列之间放置两个空格,然后用不间断空格替换剩余的单个空格。
让我们将其转换为 csv 文件,然后将其导入。这将为您提供一个数组,其中包含表示每个接口及其所有属性的对象。
1 2 3 4 5 6 7 8 9 10 11 | 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 |
这也适用于接口名称中的空格,只要单词之间只有一个空格即可。