【问题标题】:PowerShell: how to grep command output?PowerShell:如何 grep 命令输出?
【发布时间】:2009-09-28 03:04:49
【问题描述】:

PowerShell我试过了:

alias | select-string Alias

即使Alias 清楚地在输出中,这也会失败。我知道这是因为 select-string 正在对某个对象而不是实际的输出字符串进行操作。

有什么办法呢?

【问题讨论】:

    标签: powershell


    【解决方案1】:

    我觉得这个方案更简单更好,直接使用函数findstr:

    alias | findstr -i Write
    

    您也可以使用 grep 词创建别名:

    new-alias grep findstr
    

    【讨论】:

    • 这是所有其他答案中最直观、最容易记住的方法。
    • 1/2。只是为了澄清两件事,因为我有点困惑试图理解这个命令在做什么。首先是-i。如果您使用 findstr /? 显示 findstr 的帮助,它将显示以正斜杠 / 开头的所有选项。然而,它将接受带有/-'. For example ipconfig /all` 的参数在功能上与ipconfig -all 相同。所以-i/i 是一样的,因为findstr 是一个旧的DOS 程序,而且旧的DOS 程序不关心大小写,/i/I 相同。所以这意味着这是一个不区分大小写的搜索。
    • 2/2。接下来让我感到困惑的是最后的WritealiasGet-Alias 的别名,它是一个 PowerShell cmdlet。 Write 实际上是被搜索的字符串,而不是我最初认为的 Write-Output 的别名,因为彩色格式指示 PowerShell 命令。我认为 Write-Output 正在被替换为 findstr 进行搜索。它不是。所以实际发生的事情是Get-Alias 的每一行都通过管道传输到 findstr,这将在管道 str 中搜索搜索词“Write”的不区分大小写的匹配项。
    • 应该是答案。
    • 完美满足我的需求!
    【解决方案2】:

    您的问题是 alias 发出 AliasInfo 对象流,而不是 字符串流。这就是我认为你想要的。

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

    或作为函数

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

    当您不处理正在处理的事情时 (就像你刚刚运行 'alias' 时一样),shell 知道使用 ToString() 方法 在每个对象上(或使用 ETS 信息中指定的输出格式)。

    【讨论】:

    • 只是想补充一点,这适用于通用 cli 程序的输出。它模仿 Linux ./foo | grep bar 就像我想要的一样
    • 这就是我要找的东西:Get-Command |串外流| select-string Verbose Function Disable-DeliveryOptimizationVerboseLogs 1.0.2.0 DeliveryOptimization Function Enable-DeliveryOptimizationVerboseLogs 1.0.2.0 DeliveryOptimization Cmdlet Write-Verbose 7.0.0.0 Microsoft.PowerShell.Utility
    • 谢天谢地,有人发了帖子。处理来自 Unix bg 的 Powershell 对象真的很烦人。
    【解决方案3】:

    试试这个:

    PS C:\> ipconfig /displaydns | Select-String -Pattern 'www.yahoo.com' -Context 0,7
    
    >     www.yahoo.com
          ----------------------------------------
    >     Record Name . . . . . : www.yahoo.com
          Record Type . . . . . : 5
          Time To Live  . . . . : 27
          Data Length . . . . . : 8
          Section . . . . . . . : Answer
          CNAME Record  . . . . : new-fp-shed.wg1.b.yahoo.com
    

    【讨论】:

    • Pattern 字符串默认为正则表达式。在其他可选参数中,-CaseSensitive 可能很有用,因为它默认不区分大小写。
    【解决方案4】:
    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
    

    什么会与 PS 中的匹配相矛盾,然后获取字段与列中的某个值不匹配

    【讨论】:

      【解决方案5】:

      有两个问题。和问题一样,select-string 需要对输出字符串进行操作,可以从“out-string”中获得。此外, select-string 不会对通过管道传输到它的字符串进行逐行操作。这是一个通用的解决方案

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

      【讨论】:

      • 在 Powershell 1.0 中没有 -split。您可以这样做: (alias|out-string -stream) |选择字符串写入
      • 你们是不是完全没有抓住重点?您不需要 grep powershell 的输出。
      • @x0n 好吧,在某些情况下,当我通过 PS 控制台快速搜索某些内容时,我不知道和/或关心它是否属于特定属性。我发现使用Get-Member 然后在where 命令中使用正确的属性和表达式太乏味了。而grep在这方面特别好。
      • 不需要使用split。只需在Out-String 上使用-Stream 参数,然后您就可以直接通过管道传递给Select-String。
      【解决方案6】:

      如果您真的想“grep”格式化输出(显示字符串),那么请使用 Mike 的方法。肯定有这派上用场的时候。但是,如果您想尝试采用 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>
      

      注意定义属性,它是您在显示 Get-Alias(别名)的输出时看到的标题,例如:

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

      通常标题标题与属性名称匹配,但并非总是如此。这就是使用 Get-Member 派上用场的地方。它向您展示了您需要“编写”脚本的内容。现在,如果您要“grep”的是定义属性内容,请考虑这一点。您可以通过此属性的内容过滤管道中的每个 AliasInfo 对象,而不仅仅是 grepping 一个属性的值,您可以使用正则表达式来执行此操作,例如:

      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 cmdlet 根据任意脚本过滤对象。在这种情况下,我通过与正则表达式“别名”匹配的定义属性进行过滤。只有那些为该过滤器返回 true 的对象才被允许沿管道传播并被格式化以在主机上显示。

      顺便说一句,如果您正在输入此内容,那么您可以使用 Where-Object 的两个别名之一 - 'Where' 或 '?'。例如:

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

      【讨论】:

      • 您也可以使用findstr PowerShell 将为您处理文本的转换,因为它不是一个 cmdlet 而是一个程序(只是出于完整性考虑;通常,根据属性进行过滤总是更好,恕我直言:-))
      • 仅供参考,根据 Powershell 3,以下内容更简洁:gal | Where Definition -match 'alias'
      • 我觉得这是对 OP 内容的回答,而不是标题。如果我的命令是(例如)“pip freeze” - 输出只是文本。 Roi 的回答就是这个标题的意思。
      【解决方案7】:

      建议的解决方案对于可以像这样完成的事情要做很多工作:

      Get-Alias -Definition Write*
      

      【讨论】:

        【解决方案8】:

        为了更灵活和懒惰的解决方案,您可以匹配对象的所有属性。大多数情况下,这应该会让你得到你想要的行为,当它没有时你总是可以更具体。这是一个基于此原理工作的 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
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-29
          • 1970-01-01
          • 2017-11-06
          • 1970-01-01
          相关资源
          最近更新 更多