PowerShell: как вывести команду grep?
В PowerShell Я пробовал:
alias | select-string Alias
Это не удается, даже если Alias
явно отображается на выходе. Я знаю, это потому, что select-string работает на каком-то объекте, а не на фактической строке вывода.
Что можно сделать по этому поводу?
Ответы
Ответ 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
}