使用Powershell和Regex从文本文件中提取行块

时间:2018-03-06 23:35:29

标签: regex powershell text-parsing

我正在开发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,但这会显示配置文件中的所有内容。

真的很感激,如果有人可以帮助提取所有三行的端口号,以及如何使用回车符和新行匹配新行。

1 个答案:

答案 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行的块 - 相比之下,此处提供的解决方案可找到任意长度的块,只要非初始块行都有前导空格。