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

时间:2018-08-21 19:42:29

标签: arrays powershell variables foreach select-string

我陷入了从文件中提取文本的问题。这是我最终想要做的:

  1. 在特定文件中搜索短语“ NoRequest”的实例。
  2. 仅采用NoRequest的值。也就是说,如果NoRequest = true,则只会在数组中添加“ true”,而不是整行。
  3. 对文件中短语的每个实例执行此操作。

这是我正在研究的部分的片段:

$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
false
false
false
false
true
true
true
true

我尝试将代码传递到Select-Object -Last 1解决方案中,但是由于我的变量是数组,因此它选择数组中的最后一行,而不是每行的最后一个字。我还考虑过仅使用数组并执行“数组中的foreach行,除最后一个单词外的所有内容”。我猜想这会起作用,但是似乎这将是一个笨拙的解决方案。我敢肯定有一个简单有效的解决方案,但是我只是没有看到它。

4 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:3)

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

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

答案 2 :(得分:1)

对于诸如*.ini文件之类的小文件,可以使用表达式而不是管道,这是一个选项,它使解决方案既简洁又高效(PSv4 +语法):

(@(Get-content C:\Users\me\Documents\file.ini) -match 'NoRequest').ForEach({ (-split $_)[-1] })
  • @(Get-content C:\Users\me\Documents\file.ini)将指定文件的行作为数组返回(@(...)确保即使在其中恰好只有 1 行,也将返回数组文件)。

  • -match,以 array 作为LHS,充当 filter 并仅返回与指定正则表达式匹配的那些元素。

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

顺便说一句:-split operator-split '...')的 unary 形式就像古老的awk Unix utility默认情况下一样:令牌基于任何空格作为分隔符的非空运行,开头和结尾的空格被忽略。

答案 3 :(得分:0)

仅将正则表达式更改为(?<=NoRequest.* )(\w+)$,以使其与一行中的最后一个单词匹配(\w+是一个或多个单词字符,$是一行的结尾)如果其前面带有字符串“ NoRequest”。 (?<=...)是一个肯定的后置断言,它检查模式的存在而不会使其成为返回的匹配的一部分。然后扩展匹配的值。

$file = 'C:\Users\me\Documents\file.ini'
Select-String -Path $file -Pattern '(?<=NoRequest.* )(\w+)$' | ForEach-Object {
    $_.Matches.Value
}

如果最后一个单词只能是“ true”或“ false”,则可以通过以下方式将\w+替换为更具体的表达式:

Select-String -Path $file -Pattern '(?<=NoRequest.* )(true|false)$' | ForEach-Object {
    $_.Matches.Value
}