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

正在查找与特定awk命令等效的powershell,powershell,awk,Powershell,Awk,我的谷歌浏览器又让我失望了。信息(可能)就在那里,但我找不到。我对UNIX了如指掌,使用cygwin等。然而,随着服务器上Powershell可用性的提高,以及(至少在生产服务器上)安装cygwin的困难,我正在尝试使用Powershell。如果没有别的,那是我武器库中的另一件武器 本质上,我正在寻找与awk命令等效的Powershell: awk '$9 == "503" { print $0 }' < access_log 它将输入线拆分为一个数组,但我无法从这里了解如何使用选择对象

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

本质上,我正在寻找与awk命令等效的Powershell:

awk '$9 == "503" { print $0 }' < access_log
它将输入线拆分为一个数组,但我无法从这里了解如何使用
选择对象
where object
根据给定字段选择(并输出)整条线

另一种选择是
selectstring
,但我似乎看不到任何方法可以沿着
%{$\uuuu.split()[8]-eq“503”}
的行传入表达式。(我注意到powershell是基于零的,因此查看字段8)

我不确定我是否在这里遗漏了一些明显的东西,而且我还没有找到合适的google fu来提供这些信息(因此,如果这是一个被愚弄的地方,我也不会感到惊讶)

为任何帮助干杯:-)

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

cat access_log | ?{($_ -split '\s+',0,'regexmatch')[8] -eq 503} 
请注意,.NET split方法将为连续空格创建空字符串条目,因此我在PowerShell 2.0中使用-split运算符来避免这种情况

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

根据Johannes的评论更新了正则表达式模式:

cat access_log | Select-String '^\s*(?:\w+\s+){8}503'

找到了答案——尽管仍然很高兴看到是否有其他方法可以做到这一点(因此我将在几天内不回答这个问题,看看其他人是否有其他方法)。我找到的方法是:

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

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

因此,这是一个使事情按正确顺序进行的案例。最初我的思路是正确的,但有太多的管道挡住了去路。

根据您发布的代码,您希望找到第9个字段为“503”的行,然后写出这些行的第一个字段?如果是:

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

哎呀,我觉得这里的正则表达式真是太夸张了。但是谢谢你发布正则表达式的模式。我想有一种方法可以指定重复的组-应该意识到这与您在\d{3}之类的事情中使用的方法相同。:-)@基思:如果我有足够的代表留下评论,我会给你正则表达式:(您可以使用较短的别名:
gc
而不是
cat
而不是
where
——但通常您应该仅在交互使用时使用别名,而不是在可能部署在其他计算机上的脚本中使用别名。Ta用于指出拆分()不会正常化连续空格。不幸的是,我只使用PS 1…这可能会给我升级到2的理由。在PowerShell 1上,IIRC可以使用另一个重载拆分,例如
“a b
tc”。拆分(
t,[StringSplitOptions]::removemptyEntries)
PowerShell喜欢冗长,不是吗:-)与awk的简单优雅不太匹配;但它确实可以完成这项工作,而不必为重载提示安装额外的东西.Ta。希望所有这些都会有用:-)在
[StringSplitOptions]::RemoveEmptyEntries
的情况下,是.NET变得冗长,因为这是对底层.NET框架的调用。理论上,您可以为System.String.Split提供该参数的
'removeMptyEntries'
,但上次我尝试时,方法绑定器出现了混乱,无法找到正确的Split方法重载。顺便说一句,awk s/b
awk'$9==“503”'access.log
Get-Content -Path "access_log" | ForEach-Object {
    if ($_ -match '(?<Field0>\d+)\s(?:\d+\s){7}503')
    {
        Write-Host $Matches["Field0"]
    }
}
Select-String -Path "access_log" -Pattern '(?<Field0>\d+)\s(?:\d+\s){7}503' | ForEach-Object {
    Write-Host $_.Matches[0].Groups["Field0"]
}