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

PowerShell: как вывести команду grep?

В PowerShell Я пробовал:

alias | select-string Alias

Это не удается, даже если Alias явно отображается на выходе. Я знаю, это потому, что select-string работает на каком-то объекте, а не на фактической строке вывода.

Что можно сделать по этому поводу?

4b9b3361

Ответ 1

Есть две проблемы. Как и в вопросе, select-string должна работать с выходной строкой, которая может быть получена из "out-string". Кроме того, select-string не работает linewise на строках, которые передаются на него. Вот общее решение

(alias|out-string) -split "`n" | select-string Write 

Ответ 2

Если вы действительно хотите "grep" отформатированный вывод (строки отображения), переходите к подходу Майка. Есть определенные моменты, когда это пригодится. Однако, если вы хотите попробовать охватить конвейер объектов PowerShell, попробуйте это. Сначала проверьте свойства объектов, протекающих по конвейеру:

PS> alias | Get-Member


   TypeName: System.Management.Automation.AliasInfo

Name                MemberType     Definition
----                ----------     ----------
Equals              Method         bool Equals(System.Object obj)
GetHashCode         Method         int GetHashCode()
GetType             Method         type GetType()
ToString            Method         string ToString()
<snip>
*Definition*        Property       System.String Definition {get;}
<snip>

Обратите внимание на свойство Definition, которое является заголовком, который вы видите при отображении вывода Get-Alias ​​(псевдоним), например:

PS> alias

CommandType     Name           *Definition*
-----------     ----           ----------
Alias           %              ForEach-Object
<snip>

Обычно заголовок соответствует имени свойства, но не всегда. Именно здесь полезно использовать Get-Member. Он показывает вам, что вам нужно для "script". Теперь, если вы хотите "grep", это содержимое свойства определения, тогда рассмотрите это. Вместо того, чтобы просто ссылаться на одно значение свойства, вы можете вместо этого фильтровать каждый объект AliasInfo в трубке, используя содержимое этого свойства, и вы можете использовать регулярное выражение для этого, например:

PS> alias | Where-Object {$_.Definition -match 'alias'}

CommandType     Name                   Definition
-----------     ----                   ----------
Alias           epal                   Export-Alias
Alias           gal                    Get-Alias
Alias           ipal                   Import-Alias
Alias           nal                    New-Alias
Alias           sal                    Set-Alias

В этом примере я использую командлет Where-Object для фильтрации объектов на основе некоторого произвольного script. В этом случае я фильтрую свойство Defintion, сопоставляемое с псевдонимом регулярного выражения. Только те объекты, которые возвращают true для этого фильтра, могут распространяться по конвейеру и получать форматирование для отображения на хосте.

Кстати, если вы печатаете это, вы можете использовать один из двух псевдонимов для Where-Object - "Where" или "?". Например:

PS> gal | ?{$_.Definition -match '-Item*'}

Ответ 3

Я думаю, что это решение проще и лучше, используйте непосредственно функцию findstr:

alias | findstr -i Write

Вы также можете сделать псевдоним для использования слова grep:

new-alias grep findstr

Ответ 4

Ваша проблема заключается в том, что псевдоним испускает поток объектов AliasInfo, а не поток струн. Это делает то, что я думаю, что вы хотите.

alias | out-string -stream | select-string Alias

или как функция

function grep {
  $input | out-string -stream | select-string $args
}

alias | grep Alias

Если вы не обрабатываете вещи, которые находятся в стадии разработки (например, когда вы просто запускали "псевдоним" ), оболочка знает, использовать метод ToString() на каждом объекте (или использовать выходные форматы, указанные в информации ETS).

Ответ 5

Предлагаемое решение - это просто много работать для чего-то, что можно сделать следующим образом:

Get-Alias -Definition Write*

Ответ 6

Для более гибкого и ленивого решения вы можете сопоставить все свойства объектов. В большинстве случаев это должно привести к поведению, которое вы хотите, и всегда можете быть более конкретным, если это не так. Здесь используется функция grep, основанная на этом принципе:

Function Select-ObjectPropertyValues {
    param(
    [Parameter(Mandatory=$true,Position=0)]
    [String]
    $Pattern,
    [Parameter(ValueFromPipeline)]
    $input)

    $input | Where-Object {($_.PSObject.Properties | Where-Object {$_.Value -match $Pattern} | Measure-Object).count -gt 0} | Write-Output
}