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



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

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

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

$FileContents = Select-String -Path "C:UsersmeDocumentsfile.ini" -Pattern "NoRequest"

当我使用该行时,我得到以下内容:

PS> $FileContents 文档\文件.ini:222:无请求 = 假 文档\文件.ini:281:否请求 = 假 文档\文件.ini:347:无请求 = 假 文档\文件.ini:387:无请求 = 假 文档\文件.ini:1035:NOREQUEST = true 文档\文件.ini:1047:否请求 = 真 文档\文件.ini:1160:NOREQUEST = true 文档\文件.ini:1242:NOREQUEST = true

这就是我想要得到的:

PS> $FileContents 假 假 假 假 真 真 真 确实

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

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

Select-String -Path "C:UsersmeDocumentsfile.ini" -Pattern "NoRequest" |ForEach-Object {
-split $_.Line |Select-Object -Last 1
}

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

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

对于小文件(如*.ini文件(,可以选择使用表达式而不是管道,这样可以实现既简洁又高性能的解决方案(PSv4+ 语法(:

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

  • -match,以数组作为 LHS,充当过滤器,仅返回与指定正则表达式匹配的元素。

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

顺便说一句:-split运算符(-split '...'(的一形式就像Unix实用程序默认的古老awk:标记是根据任何非空的空格作为分隔符提取的,前导和尾随空格被忽略。

将正则表达式更改为(?<=NoRequest.* )(w+)$,以便它与行中的最后一个单词(w+是一个或多个单词字符,$行尾(匹配,前提是它前面有字符串"NoRequest"。(?<=...)是一个积极的后视断言,用于检查模式是否存在,而不使其成为返回的匹配项的一部分。然后展开匹配项的值。

$file = 'C:UsersmeDocumentsfile.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
}

相关内容

  • 没有找到相关文章

最新更新