Как получить захваченные группы из Select-String?
Я пытаюсь извлечь текст из набора файлов в Windows с помощью Powershell (версия 4):
PS > Select-String -AllMatches -Pattern <mypattern-with(capture)> -Path file.jsp | Format-Table
До сих пор так хорошо. Это дает хороший набор объектов MatchInfo
:
IgnoreCase LineNumber Line Filename Pattern Matches
---------- ---------- ---- -------- ------- -------
True 30 ... file.jsp ... {...}
Затем я вижу, что захваты находятся в члене совпадений, поэтому я их вынимаю:
PS > Select-String -AllMatches -Pattern <mypattern-with(capture)> -Path file.jsp | ForEach-Object -MemberName Matches | Format-Table
Что дает:
Groups Success Captures Index Length Value
------ ------- -------- ----- ------ -----
{...} True {...} 49 47 ...
или как список с | Format-List
:
Groups : {matched text, captured group}
Success : True
Captures : {matched text}
Index : 39
Length : 33
Value : matched text
Здесь, где я останавливаюсь, я понятия не имею, как идти дальше и получить список захваченных элементов группы.
Я попытался добавить еще один | ForEach-Object -MemberName Groups
, но, похоже, он возвращает то же, что и выше.
Ближайшее я получаю с | Select-Object -Property Groups
, что действительно дает мне то, что я ожидаю (список наборов):
Groups
------
{matched text, captured group}
{matched text, captured group}
...
Но тогда я не могу извлечь захваченную группу из каждого из них, я пробовал с помощью | Select-Object -Index 1
Я получаю только один из этих наборов.
Обновление: возможное решение
Кажется, что, добавив | ForEach-Object { $_.Groups.Groups[1].Value }
, я получил то, что искал, но я не понимаю, почему, поэтому я не могу быть уверен, что смогу получить правильный результат при распространении этого метода на целые множества файлов.
Почему он работает?
В качестве побочного примечания этот | ForEach-Object { $_.Groups[1].Value }
(т.е. без второго .Groups
) дает тот же результат.
Я хотел бы добавить, что при последующих попытках кажется, что команда может быть укорочена, удалив трубку | Select-Object -Property Groups
.
Ответы
Ответ 1
Посмотрите на следующие
$a = "http://192.168.3.114:8080/compierews/" | Select-String -Pattern '^http://(.*):8080/(.*)/$'
$a
теперь является MatchInfo
($a.gettype()
), он содержит свойство Matches
.
PS ps:\> $a.Matches
Groups : {http://192.168.3.114:8080/compierews/, 192.168.3.114, compierews}
Success : True
Captures : {http://192.168.3.114:8080/compierews/}
Index : 0
Length : 37
Value : http://192.168.3.114:8080/compierews/
в группе вы найдете то, что ищете, чтобы написать:
"http://192.168.3.114:8080/compierews/" | Select-String -Pattern '^http://(.*):8080/(.*)/$' | % {"IP is $($_.matches.groups[1]) and path is $($_.matches.groups[2])"}
IP is 192.168.3.114 and path is compierews