Подтвердить что ты не робот

Как получить захваченные группы из 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.

4b9b3361

Ответ 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