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" 当我使用该行时,我得到
$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)
确保即使文件中恰好只有一行,也会返回数组)@(…)
,使用数组作为LHS,充当筛选器并仅返回与指定正则表达式匹配的元素-match
- 然后,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
}