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+’ | Port Name Status Vlan Duplex Speed Type |
- 很好 :) 这将是我的下一次尝试,但我将使用 IndexOf(“Name”) 等检测索引。
- 这是非常好的!效果很好!最重要的是,我了解所有代码,甚至是正则表达式。我想我现在应该能够制作类似的脚本,而不必参考这个代码片段。谢谢!!
- 伟大的!还可以使用显式捕获使其更具可读性。例如 $regex = ‘(?<port>.{10})…’,然后是 Port = $Matches[‘port’]。
这是另一个版本,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+’ | |
试试这个。
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“ | $temp | Foreach {$_ -replace ‘(?<=\\S) (?=\\S)’,[char]0xA0 -replace ‘ +’,‘ ‘ } | |
这通过准备输入字符串来在最后一列和最后一列之间放置两个空格,然后用不间断空格替换剩余的单个空格。
- 谢谢,看来您发现了我面临的一些问题;但我没有提到。”名称”字段肯定有空格,它们都是空格分隔的;这就是我使用正则表达式拆分方法来检测至少两个空格的原因。因此,不幸的是,您提到的内容不适用于我提供的示例。
- 我已经更新了这个答案,不需要手动更改输入字符串。在我的测试中,它实际上会根据您指定的输入字符串输出正确的数据。
让我们将其转换为 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 |
这也适用于接口名称中的空格,只要单词之间只有一个空格即可。
- 谢谢,例如,我将如何查找所有状态为”已连接”的线路;并获得相应的”端口”名称?编辑:没关系…明白了:$a | ?{$_.status -eq”已连接
- 这不会为其中包含该数据的字符串产生正确的输出,即它是单个字符串 – 正如 OP 最初提出的问题。例如 $string | Foreach {$_.Trim() -replace … 产生的输出与原始输入字符串不匹配。
- 它也没有将 Speed 和 Type 拆分为单独的属性。
- 我的错。没有注意到 Speed 和 Type 只用一个空格隔开。 @KeithHill,我注意到他后来使用了 type int.txt ,所以我猜测数据已经存储到文件中。这里的字符串(我们可以拆分)只是为了在这里进行测试。 :-)
来源:https://www.codenong.com/19847341/