Я думаю, Select-String
даст лучшие результаты здесь:
((Get-Content -Path 'C:\temp\software.txt' textfile -Raw |
Select-String -Pattern '(?sm)(?<=HotFix\s*$).*?(?=^Applications:)' -AllMatches).Matches.Value).Trim()
Модификатор Regex s
используется, потому что вы ожидаете, что символ .
потенциально совпадет с символами новой строки. Модификатор Regex m
используется так, что конец строки $
и начало строки ^
могут совпадать в каждой строке. Вместе этот синтаксис (?sm)
в PowerShell.
Where {$_ -match ...}
вернет все, что делает условие истинным. Поскольку вы передаете вывод Get-Content -Raw
, все содержимое файла будет одной строкой и, следовательно, вся строка будет выводиться при условии true
.
Поскольку вы использовали -match
здесь для одной строки, все удачные совпадения будут сохраняться в переменной $matches
automati c. Ваша подходящая строка будет доступна в $matches[0]
. Если вы ожидали нескольких совпадений, -match
не будет работать так, как здесь скомпоновано.
Кроме того, метод. NET Matches()
класса Regex также может выполнять эту работу:
[regex]::Matches((Get-Content 'c:\temp\software.txt' -Raw),'(?sm)(?<=HotFix\s*$).*?(?=^Applications:)').Value.Trim()
Без Trim()
вам понадобится понять ситуацию с символом новой строки:
[regex]::Matches((Get-Content software.txt -Raw),'(?m)(?<=HotFix\r?\n?)[^\r\n]+(?=\r?\n?^Applications:)').Value
Альтернатива без регулярного выражения может использовать оператор switch
.
switch -File Software.txt -Regex {
'HotFix\s*$' { $Hotfix,$Applications = $true,$false }
'^Applications:' { $Applications = $true }
default {
if ($Hotfix -and !$Applications) {
$_
}
}
}