2

我遇到了从文件中提取文本的问题。这是我最终想做的事情:

  1. 在特定文件中搜索短语“NoRequest”的实例。
  2. 只取 NoRequest 的值。即如果NoRequest = true,那么它只会将“true”添加到数组中,而不是整行。
  3. 对文件中短语的每个实例执行此操作。

这是我正在处理的部分的片段:

$FileContents = Select-String -Path "C:\Users\me\Documents\file.ini" -Pattern "NoRequest"

当我使用那条线时,我得到以下信息:

PS> $文件内容
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> $文件内容
错误的
错误的
错误的
错误的
真的
真的
真的
真的

我尝试将代码导入Select-Object -Last 1解决方案,但由于我的变量是一个数组,它选择数组中的最后一行,而不是每行的最后一个单词。我还想过只取数组并做一个“数组中的 foreach 行,除最后一个单词之外的所有内容”。我猜这会起作用,但它似乎是一个笨拙的解决方案。我确信有一个简单有效的解决方案,但我只是没有看到它。

4

4 回答 4

5

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

Select-String -Path "C:\Users\me\Documents\file.ini" -Pattern "NoRequest" |ForEach-Object {
    -split $_.Line |Select-Object -Last 1
}
于 2018-08-21T19:51:11.100 回答
3

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

$FileContents = Get-Content "C:\Users\me\Documents\file.ini" | 
    Where{$_ -Match 'NoRequest = (true|false)'} | 
    ForEach-Object { $Matches[1] }
于 2018-08-21T20:04:49.390 回答
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,将数组作为 LHS,充当过滤器并仅返回与指定正则表达式匹配的那些元素。

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

顺便说一句:运算( ) 的一元形式的行为类似于古老的Unix 实用程序默认情况下的行为:基于任何非空的空白运行作为分隔符提取标记,忽略前导和尾随空白。-split-split '...'awk

于 2018-08-21T22:29:56.543 回答
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
}
于 2018-08-21T22:49:58.350 回答