PowerShell: how to grep command output?

前端 未结 7 1306
温柔的废话
温柔的废话 2021-01-30 08:27

In PowerShell I have tried:

alias | select-string Alias

This fails even though Alias is clearly in the output. I know this is beca

相关标签:
7条回答
  • 2021-01-30 08:35

    If you truly want to "grep" the formatted output (display strings) then go with Mike's approach. There are definitely times where this comes in handy. However if you want to try embracing PowerShell's object pipeline nature, then try this. First, check out the properties on the objects flowing down the 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>
    

    Note the Definition property which is a header you see when you display the output of Get-Alias (alias) e.g.:

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

    Usually the header title matches the property name but not always. That is where using Get-Member comes in handy. It shows you what you need to "script" against. Now if what you want to "grep" is the Definition property contents then consider this. Rather than just grepping that one property's value, you can instead filter each AliasInfo object in the pipepline by the contents of this property and you can use a regex to do it e.g.:

    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
    

    In this example I use the Where-Object cmdlet to filter objects based on some arbitrary script. In this case, I filter by the Defintion property matched against the regex 'alias'. Only those objects that return true for that filter are allowed to propagate down the pipeline and get formatted for display on the host.

    BTW if you're typing this, then you can use one of two aliases for Where-Object - 'Where' or '?'. For example:

    PS> gal | ?{$_.Definition -match '-Item*'}
    
    0 讨论(0)
  • 2021-01-30 08:39

    There are two problems. As in the question, select-string needs to operate on the output string, which can be had from "out-string". Also, select-string doesn't operate linewise on strings that are piped to it. Here is a generic solution

    (alias|out-string) -split "`n" | select-string Write 
    
    0 讨论(0)
  • 2021-01-30 08:39

    For a more flexible and lazy solution, you could match all properties of the objects. Most of the time, this should get you the behavior you want, and you can always be more specific when it doesn't. Here's a grep function that works based on this principle:

    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 讨论(0)
  • 2021-01-30 08:40
    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
    

    what would be contradict of match in PS then as in to get field not matching a certain value in a column

    0 讨论(0)
  • 2021-01-30 08:44

    Your problem is that alias emits a stream of AliasInfo objects, rather than a stream of strings. This does what I think you want.

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

    or as a function

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

    When you don't handle things that are in the pipeline (like when you just ran 'alias'), the shell knows to use the ToString() method on each object (or use the output formats specified in the ETS info).

    0 讨论(0)
  • 2021-01-30 08:54

    I think this solution is easier and better, use directly the function findstr:

    alias | findstr -i Write
    

    You can also make an alias to use grep word:

    new-alias grep findstr
    
    0 讨论(0)
提交回复
热议问题