Powershell Select-Object против ForEach для результатов Select-String - PullRequest
3 голосов
/ 09 сентября 2011

Допустим, у меня есть результаты вызова Select-String в переменной $ mat, разбирающего регулярное выражение из содержимого файла:

$mat = cat errors.txt | Select-String "'(?<code>\w+)'.+ID (?<id>[^:]+)" 

Согласно выводу $mat | Get-Member результат содержит свойство Matches типа Match[].

Когда я выполняю следующее, я получаю все совпадения с моим выводом регулярного выражения:

PS > $mat | Select-Object -Property Matches

Matches                                                                                                                                                                              
-------                                                                                                                                                                              
{'ACCFWD', ID 16}                                                                                                                                                                    
{'EQASIAN', ID 448}                   

Почему следующий блок кода, использующий foreach для выбора совпадений, не имеет такой же вывод:

    PS > $mat | ForEach { $_.Matches } 


Groups   : {'ACCFWD', ID 16, ACCFWD, 16}
Success  : True
Captures : {'ACCFWD', ID 16}
Index    : 20
Length   : 15
Value    : 'ACCFWD', ID 16

Groups   : {'EQASIAN', ID 448, EQASIAN, 448}
Success  : True
Captures : {'EQASIAN', ID 448}
Index    : 20
Length   : 17
Value    : 'EQASIAN', ID 448

Спасибо!

Ответы [ 2 ]

9 голосов
/ 09 сентября 2011

При отображении свойств PowerShell автоматически форматирует свойства типов, формат отображения которых не определен в файле *.format.ps1xml, в виде таблицы для максимум 4 свойств. 5 или более свойств отображаются в виде списка. Когда вы выбираете свойство Matches с помощью Select-Object, вы выбираете одно свойство объекта Microsoft.PowerShell.Commands.MatchInfo. С Foreach-Object вы отображаете все свойства объекта System.Text.RegularExpressions.Match.

Использование Select-Object -ExpandProperty Matches приведет к тому, что выходные данные будут выглядеть так же, как Foreach, потому что будут выводиться RegularExpressions.Match объекты.

Если вы поместите Get-Member после обоих примеров, которые производят вывод, вы увидите, что они выводят объекты различных типов.

Редактировать: Вот объяснение форматирования, которое происходит для каждой команды.

cat errors.txt | Select-String "'(?<code>\w+)'.+ID (?<id>[^:]+)"

Вывод Select-String - это объект Microsoft.PowerShell.Commands.MatchInfo, который имеет 8 свойств. Эти свойства не отображаются по умолчанию, поскольку формат отображения MatchInfo определен в PowerShellCore.format.ps1xml для отображения результата метода MatchInfo ToString().

$mat | Select-Object -Property Matches

В этом случае вывод Select-Object представляет собой пользовательский объект Selected.Microsoft.PowerShell.Commands.MatchInfo со свойством Matches, которое было скопировано из объекта MatchInfo. Поскольку для типа Selected.Microsoft.PowerShell.Commands.MatchInfo не задан формат отображения по умолчанию, PowerShell автоматически форматирует его в виде таблицы, поскольку он имеет менее 5 свойств (в этом случае Matches является единственным свойством).

$mat | ForEach { $_.Matches } 

В Foreach-Object ScriptBlock выводится свойство Matches объекта MatchInfo. Свойство Matches является System.Text.RegularExpressions.Match, которое имеет 6 свойств. Поскольку для типа System.Text.RegularExpressions.Match не задан формат отображения по умолчанию, объекты Match отображаются в виде списка, поскольку имеется более 4 свойств.

1 голос
/ 09 сентября 2011

Если вы используете -ExpandProperty вместо -Property, тогда оба выхода будут одинаковыми.

$mat | Select-Object -ExpandProperty Matches

Это работает для данного конкретного примера, но для доступа к одному свойству, Select-Object -ExpandPropertyвсе еще не совсем так же, как ForEach во всех случаях.Я бы использовал ForEach.Также см. Этот пример: http://community.idera.com/powershell/powertips/b/tips/posts/use-foreach-object-instead-of-select-object-expandproperty

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...