我有以下示例文本正在尝试为其创建捕获。
object-group network og-n-sna-EWB-UAT-srvrs-4
network-object host 10.34.68.108
network-object host 10.34.68.109
network-object host 10.34.68.110
object-group network og-n-bng-ind-users
network-object object obj-FAIBLR04L1025
network-object object obj-FAIBLR04L1741
network-object object obj-FAIBLR04L1344
network-object object obj-FAIBLR04L1193
network-object object obj-FAIBLR06L1318
object-group network og-n-mdm-srvrs-7
network-object host 10.36.50.101
network-object host 10.36.50.102
现在,我试图弄清楚如何捕获对象 obj-FAIBLR04L1344 的对象组( og-n-bng-ind-users )强>是其中的一部分。
我尝试过结合
*\snetwork-object\sobject\sobj-FAIBLR04L1344*
,但后面却看不见,但我无法使用它。有没有人知道如何构造此正则表达式以与PowerShell一起使用?
答案 0 :(得分:1)
假设文本存储在text.txt
中,我相信这可能有效:
Get-Content -Raw text.txt |
Select-String `
-AllMatches `
-Pattern '(?<=object-group network ).+(?=(\s*network-object object .*)*\s*network-object object obj-FAIBLR04L1344)' |
foreach {$_.Matches.Value}
Get-Content -Raw
将text.txt
的内容作为单个对象(多行字符串)传递到Select-String
。 -AllMatches
选项显示所有匹配项,而不是仅显示第一个匹配项(如果对象在示例文本中位于多个组中)。 -Pattern
选项接收要搜索的模式。此模式对object-group network
使用先行查找,对零个或多个\s*network-object object .*
后跟\s*network-object object obj-FAIBLR04L1344
进行先行查找。
Select-String
打印匹配的行(在这种情况下为整个文本)。为避免这种情况,foreach {$_.Matches.Value}
会在匹配项上进行迭代并显示其值。
答案 1 :(得分:0)
确定要在这里使用RegEx吗?
准备:
$text = @'
object-group network og-n-sna-EWB-UAT-srvrs-4
network-object host 10.34.68.108
network-object host 10.34.68.109
network-object host 10.34.68.110
object-group network og-n-bng-ind-users
network-object object obj-FAIBLR04L1025
network-object object obj-FAIBLR04L1741
network-object object obj-FAIBLR04L1344
network-object object obj-FAIBLR04L1193
network-object object obj-FAIBLR06L1318
object-group network og-n-mdm-srvrs-7
network-object host 10.36.50.101
network-object host 10.36.50.102
'@
$networkObjectId = 'obj-FAIBLR04L1344' + [System.Environment]::NewLine
变量:
$objectGroupListFound = @($text.Split([string[]]@('object-group'), [System.StringSplitOptions]::RemoveEmptyEntries) |
Where-Object { $_.Contains( "network-object object $($networkObjectId)" ) } |
ForEach-Object { $_.Split([System.Environment]::NewLine)[0]} |
ForEach-Object { $_.Split()[-1]} )
if ($objectGroupListFound.Count -ne 1)
{
Write-Error "No objectGroup found for networkObjectId $($networkObjectId) or found more than one. Found $($objectGroupListFound.Count)."
}
## There I omit "else", assuming code upper is wrapped into try block and on error, it will not reach this line.
$objectGroup = $objectGroupListFound[0]
变量:
$tempText = $text.Substring(0,$text.IndexOf($networkObjectId))
$tempText = $tempText.Substring($tempText.LastIndexOf('object-group'))
$objectGroup = $tempText.Split("`r`n".ToCharArray(), [System.StringSplitOptions]::RemoveEmptyEntries)[0].Split(' ', [System.StringSplitOptions]::RemoveEmptyEntries)[2]
Variant(逐行显示)-我认为这是最简单明了的
$text = [System.IO.File]::ReadAllLines($path)
# or $text = $text.Split([char[]]"`r`n", [System.StringSplitOptions]::RemoveEmptyEntries)
$networkObjectId = "obj-FAIBLR04L1344"
$objectGroupCache = $null
$objectGroup = $null
for ($i = 0; $i -lt $text.Count; $i++)
{
if ($text[$i].Trim().StartsWith('object-group network'))
{
# We are entering this group.
$objectGroupCache =$text[$i].Split([char[]]" `t", [System.StringSplitOptions]::RemoveEmptyEntries)[-1]
}
elseif ($text[$i].Trim().StartsWith('network-object') -and $text[$i].Trim().EndsWith($networkObjectId))
{
$objectGroup = $objectGroupCache
break;
}
}
if ([String]::IsNullOrWhiteSpace($objectGroup))
{
Write-Error "Not found"
}
答案 2 :(得分:0)
另一种方法是使用ConvertFrom-String。这适用于您的小样本数据。模板很有可能需要更多的“训练”数据。建立在其上的technology很棒。
$template = @'
object-group network og-n-sna-EWB-UAT-srvrs-4
network-object host 10.34.68.108
network-object host 10.34.68.109
network-object host 10.34.68.110
object-group network {Name: og-n-bng-ind-users}
network-object object obj-FAIBLR04L1025
network-object object obj-FAIBLR04L1741
network-object object obj-FAIBLR04L1344
network-object object obj-FAIBLR04L1193
network-object object obj-FAIBLR06L1318
object-group network og-n-mdm-srvrs-7
network-object host 10.36.50.101
network-object host 10.36.50.102
'@
@'
object-group network og-n-sna-EWB-UAT-srvrs-4
network-object host 10.34.68.108
network-object host 10.34.68.109
network-object host 10.34.68.110
object-group network og-n-bng-ind-users
network-object object obj-FAIBLR04L1025
network-object object obj-FAIBLR04L1741
network-object object obj-FAIBLR04L1344
network-object object obj-FAIBLR04L1193
network-object object obj-FAIBLR06L1318
object-group network og-n-mdm-srvrs-7
network-object host 10.36.50.101
network-object host 10.36.50.102
'@ | ConvertFrom-String -TemplateContent $template
或者来自文件
Get-Content $file | ConvertFrom-String -TemplateContent $template
Name
----
og-n-bng-ind-users
答案 3 :(得分:0)
您还可以选择将整个文件解析为PSObjects数组,这不仅可以轻松获取您要查找的任何项目,而且还可以将文件另存为CSV文件,以便在Excel中使用。
$result = switch -Regex -File 'D:\Test\thefile.txt' {
'^object-group network ' { $group = ($_.Trim() -split '\s')[-1] }
'network-object' {
$item = $_.Trim() -split '\s'
[PsCustomObject]@{
Group = $group
Type = $item[1]
Value = $item[2]
}
}
}
一旦将此文件转换为对象数组,就可以得到任何东西 您需要它,例如值'obj-FAIBLR04L1344'的对象组名称
($result | Where-Object { $_.Value -eq 'obj-FAIBLR04L1344' }).Group # --> og-n-bng-ind-users