代码之家  ›  专栏  ›  技术社区  ›  Callie J

正在查找与特定awk命令等效的powershell

  •  3
  • Callie J  · 技术社区  · 15 年前

    我的googlefu又让我失望了。信息(可能)在外面,但我找不到。我对UNIX了如指掌,使用cygwin等。然而,随着服务器上Powershell可用性的提高,以及(至少在生产服务器上)cygwin就位的困难,我正在尝试使用Powershell。如果没有别的,那是我武器库里的另一件武器。

    awk '$9 == "503" { print $0 }' < access_log
    

    我知道我可以这样使用split:

    cat access_log | %{ $_.split() }
    

    它将引入线分割成一个数组,但我无法从这里计算出如何使用 select-object where-object 根据给定的字段选择(并输出)整行。

    select-string 但我似乎看不出有什么方法可以把一个表达式 %{ $_.split()[8] -eq "503" }

    我不确定我是否在这里遗漏了一些明显的东西,而且我还没有找到合适的googlefu来给我提供这些信息(所以如果这是一个被欺骗的地方,我也不会感到惊讶)。

    为任何帮助干杯:-)

    3 回复  |  直到 15 年前
        1
  •  4
  •   Keith Hill    15 年前

    是的,在这种情况下,对象(别名?)的位置更好:

    cat access_log | ?{($_ -split '\s+',0,'regexmatch')[8] -eq 503} 
    

    请注意,.NET split方法将为连续空格创建空字符串条目,因此我在PowerShell 2.0中使用-split操作符来避免这种情况。

    我的正则表达式在这方面很弱,但我想有一种方法可以使用正则表达式获得第9个字段(比下面的“脑死”方法更容易-任何人??):

    根据Johannes的评论更新了regex模式:

    cat access_log | Select-String '^\s*(?:\w+\s+){8}503'
    
        2
  •  3
  •   Callie J    15 年前

    cat access_log | where-object { $_.split()[8] -eq "503" }
    

    可以缩写为:

    cat access_log | where { $_.split()[8] -eq 503 }
    

    所以这是一个让事情按正确的顺序进行的案例。我本来是沿着正确的路线,但坚持太多的管道的方式。

        3
  •  0
  •   George Howarth    15 年前

    据我所知,从您发布的代码,您正在寻找第9个字段是'503'的行,然后写出这些行的第一个字段?如果是:

    Get-Content -Path "access_log" | ForEach-Object {
        if ($_ -match '(?<Field0>\d+)\s(?:\d+\s){7}503')
        {
            Write-Host $Matches["Field0"]
        }
    }
    

    编辑:

    Select-String (比我以前的好):

    Select-String -Path "access_log" -Pattern '(?<Field0>\d+)\s(?:\d+\s){7}503' | ForEach-Object {
        Write-Host $_.Matches[0].Groups["Field0"]
    }