web-dev-qa-db-fra.com

PowerShell: comment afficher la sortie de la commande grep?

Dans PowerShell j'ai essayé:

alias | select-string Alias

Cela échoue même si Alias est clairement dans la sortie. Je sais que c'est parce que select-string opère sur un objet et non sur la chaîne de sortie réelle. 

Que peut-on faire à ce sujet?

42
Ian Kelling

Il y a deux problèmes. Comme dans la question, select-string doit agir sur la chaîne de sortie, qui peut être obtenue à partir de "out-string". En outre, select-string ne fonctionne pas ligne par ligne sur les chaînes qui lui sont raccordées. Voici une solution générique

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

Je pense que cette solution est plus simple et meilleure, utilisez directement la fonction findstr:

alias | findstr -i Write

Vous pouvez également créer un alias pour utiliser grep Word:

new-alias grep findstr
41
Roi

Votre problème est que l’alias émet un flux d’objets AliasInfo, plutôt qu’un astream de chaînes. Cela fait ce que je pense que tu veux.

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

ou en fonction

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

alias | grep Alias

Lorsque vous ne gérez pas des éléments du pipeline (Comme lorsque vous venez d'exécuter "alias"), le Shell sait utiliser la méthode ToString () Sur chaque objet l'info ETS).

33
Mike Shepard

Si vous voulez vraiment "grep" la sortie formatée (afficher les chaînes), alors optez pour l'approche de Mike. Il y a certainement des moments où cela est utile. Toutefois, si vous souhaitez adopter la nature du pipeline d'objets de PowerShell, essayez ceci. Commencez par vérifier les propriétés des objets s’écoulant dans le pipeline:

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>

Notez la propriété Definition qui est un en-tête que vous voyez lorsque vous affichez la sortie de Get-Alias ​​(alias), par exemple:

PS> alias

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

Habituellement, le titre de l'en-tête correspond au nom de la propriété, mais pas toujours. C’est là que l’utilisation de Get-Member est utile. Il vous montre ce que vous devez "script" contre. Maintenant, si ce que vous voulez "grep" est le contenu de la propriété Definition, alors considérez ceci. Plutôt que de simplement rechercher la valeur d'une propriété, vous pouvez filtrer chaque objet AliasInfo dans le pipeline par le contenu de cette propriété et vous pouvez utiliser une expression régulière pour le faire, par exemple:

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

Dans cet exemple, j'utilise l'applet de commande Where-Object pour filtrer des objets en fonction d'un script quelconque. Dans ce cas, je filtre en fonction de la propriété Defintion comparée à l'expression régulière "alias". Seuls les objets qui renvoient true pour ce filtre sont autorisés à se propager dans le pipeline et à être formatés pour être affichés sur l'hôte. 

BTW si vous tapez ceci, alors vous pouvez utiliser l’un des deux alias pour Where-Object - 'Where' ou '?'. Par exemple:

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

La solution proposée consiste à faire beaucoup de travail pour quelque chose qui peut être fait comme ceci:

Get-Alias -Definition Write*
4
mjsr

Pour une solution plus souple et paresseuse, vous pouvez associer toutes les propriétés des objets. La plupart du temps, cela devrait vous amener au comportement que vous voulez, et vous pouvez toujours être plus précis quand ce n'est pas le cas. Voici une fonction grep basée sur ce principe:

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
}
0
Marty Gentillon