【问题标题】:Use Powershell and Regex to extract block of lines from a text file使用 Powershell 和 Regex 从文本文件中提取行块
【发布时间】:2018-03-06 23:35:29
【问题描述】:

我正在开发 Powershell 脚本和 .Net Regex,以使用 powershell 和 regex 在网络设备配置中查找模式匹配。我在尝试从配置文件中提取字符串块时遇到问题,并且在编写正则表达式语句以匹配回车符和新行时遇到问题。下面是我的例子。我有一个配置文件,下面有我要提取的信息

vlan 没有描述端口 999 未使用 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 未使用 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,但这会显示配置文件中的所有内容。

如果有人可以帮助提取带有端口号的所有三行以及如何使用回车符和换行符来匹配新行,我将不胜感激。

【问题讨论】:

  • 你想得到什么?只是上面文字中的三行?使用get-content c:\config.txt -raw 方法,然后尝试简单的(?m)^999.*(?:\r?\n.*){2}
  • 你有一个贪婪的量词 (.*),所以是的,当你使用它时它会得到 everything。您可能希望将其更改为 .*? 以获得更好的结果。是的,你需要使用-raw。查看更多文件会很有帮助。
  • 谢谢。我尝试了 -raw ,它显示了整个配置,其中包含许多我不需要的其他信息。你能解释一下 (?:\r?\n.*){2} 的作用吗?我现在没有配置文件,明天尝试上传
  • @Justin: (?:..) 是一个非捕获组(用于在不需要单独捕获内部内容的情况下); \r?\n 匹配 Windows 和 Unix 样式的换行符(CRLF 和 LF)。 (?:\r?\n.*){2} 因此unconditionally 匹配下两行(注意选项s 的省略如何使. not 匹配\n),这与您的特定的示例输入 - 但是,如果您的实际输入包含具有不同行数的块,则它会不足。

标签: regex powershell text-parsing


【解决方案1】:

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
}

正则表达式也需要一些调整,包括使用 non-greedy 量词 .*?,正如 TheMadTechnician 所建议的那样:

  • (?ms) 设置正则表达式选项m(将^$ 视为line 锚点)和s(使. 匹配\n(换行符) ) 太`。

  • ^999.*? 非贪婪地匹配任何以999 开头的行和任何后续字符。

  • (?=\r?\n\S|\Z) 是一个正前瞻断言 ((?=...)),它匹配换行符 (\r?\n) 后跟非空白字符 (\S) - 假定是 next 块的开始 - 或 (|) 输入的最后 (\Z) - 实际上,这匹配文件的结尾或开头的下一个块,但不包括在$Matches中记录的匹配中。


[1] Wiktor 还建议使用正则表达式 (?m)^999.*(?:\r?\n.*){2},它适用于示例输入,但仅限于恰好有 3 行的块 - 相比之下,此处提供的解决方案可以找到任意长度的块,如只要非初始块行都有前导空格。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    • 2011-12-10
    • 1970-01-01
    • 2021-07-30
    相关资源
    最近更新 更多