我正在开发Powershell脚本和.Net Regex,以使用powershell和regex在网络设备配置中查找模式匹配。我有问题尝试从配置文件中提取字符串块,并且还有问题写入正则表达式语句以匹配回车符和新行。以下是我的例子。我有一个配置文件,其中包含我要提取的信息
vlan no description ports 999 unused Gi1/2,Gi1/3, Gi1/4, Gi1/5, Gi1/6, Gi/7, Gi/8, Gi1/9 Gi1/0, Gi1/11, Gi1/12, Gi1/13, Gi1/14, Gi1/15, Gi1/16 Gi1/17, Gi1/18
这是我的代码
$File = Get-content C:\config.txt
$Regex = "(?sm)(^999.*(\r\n\s+.*)"
$unused_ports = Select-String -path $File -Pattern $Regex
Write-host $Unused_ports
它只显示第一行
999 unused Gi1/2,Gi1/3, Gi1/4, Gi1/5, Gi1/6, Gi/7, Gi/8, Gi1/9
我也试过以下$ Regex
$Regex = '(?m)(^999.*\s+Gi1/10.*)
$Regex = '(?m)(^999.*\r\n\s+Gi1/10.*)
但我使用的正则表达式语句都没有提取所有端口(3行)
我也使用了get-content c:\config.txt -raw
,但这会显示配置文件中的所有内容。
真的很感激,如果有人可以帮助提取所有三行的端口号,以及如何使用回车符和新行匹配新行。
答案 0 :(得分:2)
Wiktor Stribiżew在关于 [1] 问题的评论中提供了关键指针
:您必须使用Get-Content -Raw
将文件内容读入单字符串,这样您的正则表达式可以匹配跨行:
if ((Get-Content -Raw C:\Config.txt) -match '(?ms)^999.*?(?=\r?\n\S|\Z)') {
$Matches[0] # automatic variable $Matches reflects what was captured
}
正则表达式也需要进行一些调整,包括使用非贪婪的量词.*?
,如TheMadTechnician所示:
(?ms)
设置正则表达式选项m
(将^
和$
视为行锚点)和s
(使.
匹配\n
(换行符)。
^999.*?
匹配以999
开头的任何行以及非贪婪的任何后续字符。
(?=\r?\n\S|\Z)
是一个积极的预见断言((?=...)
),它匹配换行符(\r?\n
)后跟非空格字符(\S
) - 假设是 next 块的开头 - 或(|
)输入的最后一端(\Z
) - 实际上,这匹配文件的结尾或下一个块的开头,但不包含在$Matches
中记录的匹配中。
[1] Wiktor还建议正则表达式(?m)^999.*(?:\r?\n.*){2}
,它适用于样本输入,但仅限于具有正好3行的块 - 相比之下,此处提供的解决方案可找到任意长度的块,只要非初始块行都有前导空格。