Arrays 从选择字符串中提取每行的最后一个单词

Arrays 从选择字符串中提取每行的最后一个单词,arrays,powershell,variables,foreach,select-string,Arrays,Powershell,Variables,Foreach,Select String,我遇到了从文件中提取文本的问题。以下是我最终想要做的: 在特定文件中搜索短语“NoRequest”的实例 只取NoRequest的值。i、 e.如果NoRequest=true,那么它将只向数组中添加“true”,而不是整行 对文件中短语的每个实例执行此操作 以下是我正在研究的部分的一个片段: $FileContents = Select-String -Path "C:\Users\me\Documents\file.ini" -Pattern "NoRequest" 当我使用该行时,我得到

我遇到了从文件中提取文本的问题。以下是我最终想要做的:

  • 在特定文件中搜索短语“NoRequest”的实例
  • 只取NoRequest的值。i、 e.如果NoRequest=true,那么它将只向数组中添加“true”,而不是整行
  • 对文件中短语的每个实例执行此操作
  • 以下是我正在研究的部分的一个片段:

    $FileContents = Select-String -Path "C:\Users\me\Documents\file.ini" -Pattern "NoRequest"
    
    当我使用该行时,我得到以下信息:

    PS> $FileContents Documents\file.ini:222:NoRequest = false Documents\file.ini:281:NoRequest = false Documents\file.ini:347:NoRequest = false Documents\file.ini:387:NoRequest = false Documents\file.ini:1035:NOREQUEST = true Documents\file.ini:1047:NoRequest = true Documents\file.ini:1160:NOREQUEST = true Documents\file.ini:1242:NOREQUEST = true PS>$FileContents Documents\file.ini:222:NoRequest=false Documents\file.ini:281:NoRequest=false Documents\file.ini:347:NoRequest=false Documents\file.ini:387:NoRequest=false Documents\file.ini:1035:NOREQUEST=true Documents\file.ini:1047:NoRequest=true Documents\file.ini:1160:NOREQUEST=true Documents\file.ini:1242:NOREQUEST=true 这就是我想要的:

    PS> $FileContents false false false false true true true true PS>$FileContents 假的 假的 假的 假的 真的 真的 真的 真的
    我尝试将代码管道化到
    Select Object-Last 1
    解决方案中,但由于我的变量是一个数组,它选择数组中的最后一行,而不是每行的最后一个字。我还考虑过只取数组,做一个“数组中的每一行,除了最后一个单词之外,把所有的东西都切掉”。我猜这会奏效,但这似乎是一个笨拙的解决方案。我确信有一个简单而有效的解决方案,但我没有看到它。

    您可以在字符串上使用
    -split
    ,并获取最后的结果:

    Select-String -Path "C:\Users\me\Documents\file.ini" -Pattern "NoRequest" |ForEach-Object {
        -split $_.Line |Select-Object -Last 1
    }
    

    或者,您可以读入该文件,将其传递到
    Where
    语句以查找所需的行,然后使用
    $Matches
    自动变量

    $FileContents = Get-Content "C:\Users\me\Documents\file.ini" | 
        Where{$_ -Match 'NoRequest = (true|false)'} | 
        ForEach-Object { $Matches[1] }
    

    对于小型文件(如
    *.ini
    文件),使用表达式而不是管道是一种选择,它支持简洁且性能良好的解决方案(PSv4+语法):

    • @(获取内容C:\Users\me\Documents\file.ini)
      将指定文件的行作为数组返回(
      @(…)
      确保即使文件中恰好只有一行,也会返回数组)

    • -match
      ,使用数组作为LHS,充当筛选器并仅返回与指定正则表达式匹配的元素

    • 然后,PSv4+
      .ForEach()
      方法作用于结果数组的元素,通过空格(
      -split
      )将每个元素拆分为令牌,并返回最后一个令牌(
      -1


    顺便说一句:(
    -split'.'
    )的一元形式在默认情况下的行为类似于尊者:标记是基于任何非空的空格作为分隔符提取的,前导空格和尾随空格被忽略。

    将正则表达式更改为
    (?我一直喜欢
    处理每个对象的方法{$\.Line.Trim().Split('')[-1]}
    。我想有些人会对循环中的嵌入式管道感到困惑,并且不知道他们在处理什么管道。这并不十分明显,但默认情况下,
    awk
    就是这样做的,也许这就是PowerShell选择的模型。
    (@(Get-content C:\Users\me\Documents\file.ini) -match 'NoRequest').ForEach({ (-split $_)[-1] })
    
    $file = 'C:\Users\me\Documents\file.ini'
    Select-String -Path $file -Pattern '(?<=NoRequest.* )(\w+)$' | ForEach-Object {
        $_.Matches.Value
    }
    
    Select-String -Path $file -Pattern '(?<=NoRequest.* )(true|false)$' | ForEach-Object {
        $_.Matches.Value
    }