Powershell将正则表达式值保留在变量中,然后构建字符串



我想从不同的正则表达式中捕获值,以便构建端点运行状况检查的文件列表。

我有一些PS脚本可以正确解析和提取某些txt文件中的信息,但是我想使用脚本中不同正则表达式中捕获的值来编写新字符串。

我下面的脚本从 txt 文件 #1 读取并输出 txt 文件 #2,一切正确。

PS脚本

(Get-Content 'c:fake_pathtest_stack.txt') `
| Select-String '(^S{5}SERVER:)(S*)(S{5})','(^S*n:"*:)(d*)(:"s$)','(^"/)(S*)("s$)' -AllMatches | Foreach-Object {$_.Matches} | 
Foreach-Object {$_.Groups[2].Value} |
Out-File c:fake_pathdemo_stack.txt

1 个文件内

*****SERVER:WIN001*****
SITE.NAME:"PRJ_ABC"
bindingInformation:"*:80:" 
"/App001" 
*****SERVER:WIN002*****
SITE.NAME:"PRJ_DEF"
bindingInformation:"*:81:" 
"/App001" 
SITE.NAME:"PRJ_HIJ"
bindingInformation:"*:82:" 
"/App001" `

2 输出文件

WIN001
80
App001
WIN002
81
App001
82
App001`

但是,我希望将下面 3 个不同正则表达式中捕获的值用于 3 个不同的变量,比如说 $a、$b 和 $c。

(Select-String '(^S{5}SERVER:)(S*)(S{5})','(^S*n:"*:)(d*)(:"s$)','(^"/)(S*)("s$)')

我的尝试:

Foreach-Object 'http://' + 'a.{$_.Groups[2].Value}' + ':' + '$b.{$_.Groups[2].Value}' + '/' + '$c.{$_.Groups[2].Value}' + '/api/status'

我的尝试的所需输出(写在上面)

一个新文件组成如下: http://WIN001:80/App001/api/status http://WIN002:81/App001/api/status http://WIN002:81/App001/api/status 如您所见,我想在变量 $a $b 和 $c 中捕获正则表达式,然后连接字符串,如 http://+ $a + ':' + $b + .....等等,为了格式化它并生成一个 URL。

我相信这是可行的,只是缺乏背景。

欢迎所有的建议,干杯;-)

我遵循一种更简单的方法,

  • 每个输入行都针对 3 个非常简单的正则表达式进行检查,这些表达式具有命名的捕获组,
  • 如果第一个两个匹配,则设置一个变量,
  • 如果最后一个与 URL 匹配,则输出收集的数据:

## Q:Test2019412SO_55655078.ps1
(Get-Content '.test_stack.txt')| ForEach-Object {
if($_ -match 'SERVER:(?<server>[^*]+)'){$Server = $Matches.Server}
if($_ -match ':(?<port>d{2,5}):'     ){$Port   = $Matches.Port}
if($_ -match '^"(?<App>[^"]+)"'     ){
"http://{0}:{1}{2}/api/status" -f $Server,$Port,$Matches.App
}
} # | Set-Content '.demo_stack.txt'

示例输出:

> Q:Test2019412SO_55655078.ps1
http://WIN001:80/App001/api/status
http://WIN002:81/App001/api/status
http://WIN002:82/App001/api/status

顺便说一句,您的第 3 个示例行是错误的,它应该有端口 82。

这有点丑,但它有效:

$file = Get-Content "c:somefile.txt" -Raw
ForEach ($entry in ($file -split "(?m)^*{5}").trim()) {
$server = (Select-String -InputObject $entry -Pattern "(?m)(?<=SERVER:)(?<Server>.*?)(?=*+.*$)" -AllMatches).matches.value -as [array]
$ports = (Select-String -InputObject $entry -Pattern "(?m)(?<=:`".*?:)(?<port>d+)(?=:`".*$)" -AllMatches).matches.value -as [array]
$apps = (Select-String -InputObject $entry -Pattern "(?m)(?<=^`")(?<app>/.*?)(?=`".*$)" -AllMatches).matches.value -as [array]
for ($i = 0; $i -lt $ports.count; $i++) {
"http://" + $server + ":" + $ports[$i] + $apps[$i] + "/api/status" | Out-File -FilePath "NewFile.txt" -Append
}
}

我使用-Split方法按服务器条目划分文件。这些条目中的每一个都是一个数组元素,在循环迭代时存储在$entry中。我通过匹配任何以 5 * 字符 (^*{5}开头的行进行拆分。.trim()方法只是删除拆分输出中间的空白行。

$server是一个数组,分配了表示服务器名称的匹配文本来自条目。

  • (?m)是多行修饰符。这样^$将匹配每行的开头和结尾。
  • (?<=SERVER:)是一个积极的回溯,可以在处理字符串SERVER:的位置开始匹配。
  • (?<Server>.*?)是名为"服务器"的捕获组,用于保存服务器名称字符串。
  • (?=*+.*$)是对一个或多个 * 字符后跟任何字符,然后是行尾的正面展望。

$ports是一个数组,分配了绑定属性中的所有端口号。

  • (?<=:`".*?:)正面的回溯:",后跟尽可能多的字符,后跟
  • (?<port>d+)是表示端口号的命名捕获组端口
  • (?=:`".*$)是正面的展望:",然后是任何字符,直到行尾

$apps是分配了单独存在于一行上的所有应用程序目录的数组

  • (?<=^`")是对以">
  • (?<app>/.*?)是捕获组应用,表示不带引号的匹配应用程序路径。它捕获/和任何字符,直到达到">
  • (?=`".*$)是一个积极的前瞻检查 ",后跟任何字符,直到行尾

for循环假定每个服务器的端口号与应用程序路径的数量一样多。上面的每个变量都是数组的原因是,当可能只有一个元素存在时,可以使用与任何其他元素相同的语法访问第一个元素[0]。循环输出字符串串联,每次迭代都可能输出不同的端口和应用程序路径组合。每个字符串都输出到NewFile.txt

相关内容

最新更新