[英]How to select the first matching line after an already matched line in powershell?
I am trying to use powershell to query some Windows power settings from the output of powercfg
. 我正在尝试使用powershell从powercfg
的输出查询一些Windows电源设置。 I have enough information to narrow down the range to a subgroup of settings, but within the text block I still need to find a matching setting using a GUID, and then I need to extract the currently set value of the setting. 我有足够的信息来将范围缩小到一组子设置,但是在文本块中,我仍然需要使用GUID查找匹配的设置,然后需要提取该设置的当前设置值。 I was able to achieve this using Select-String -Context
, but it's not dynamic and thus error-prone. 我能够使用Select-String -Context
实现此Select-String -Context
,但是它不是动态的,因此容易出错。 I am looking for a cleaner way to extract the value. 我正在寻找一种更干净的方法来提取价值。
Here is a sample of the text block I have (stored in $block
): 这是我拥有的文本块的一个示例(存储在$block
):
Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)
GUID Alias: SCHEME_BALANCED
Subgroup GUID: 238c9fa8-0aad-41ed-83f4-97be242c8f20 (Sleep)
GUID Alias: SUB_SLEEP
Power Setting GUID: 29f6c1db-86da-48c5-9fdb-f2b67b1f44da (Sleep after)
GUID Alias: STANDBYIDLE
Minimum Possible Setting: 0x00000000
Maximum Possible Setting: 0xffffffff
Possible Settings increment: 0x00000001
Possible Settings units: Seconds
Current AC Power Setting Index: 0x00000708
Current DC Power Setting Index: 0x00000384
Power Setting GUID: 94ac6d29-73ce-41a6-809f-6363ba21b47e (Allow hybrid sleep)
GUID Alias: HYBRIDSLEEP
Possible Setting Index: 000
Possible Setting Friendly Name: Off
Possible Setting Index: 001
Possible Setting Friendly Name: On
Current AC Power Setting Index: 0x00000001
Current DC Power Setting Index: 0x00000001
Power Setting GUID: 9d7815a6-7ee4-497e-8888-515a05f02364 (Hibernate after)
GUID Alias: HIBERNATEIDLE
Minimum Possible Setting: 0x00000000
Maximum Possible Setting: 0xffffffff
Possible Settings increment: 0x00000001
Possible Settings units: Seconds
Current AC Power Setting Index: 0x00002a30
Current DC Power Setting Index: 0x00002a30
Power Setting GUID: bd3b718a-0680-4d9d-8ab2-e1d2b4ac806d (Allow wake timers)
GUID Alias: RTCWAKE
Possible Setting Index: 000
Possible Setting Friendly Name: Disable
Possible Setting Index: 001
Possible Setting Friendly Name: Enable
Possible Setting Index: 002
Possible Setting Friendly Name: Important Wake Timers Only
Current AC Power Setting Index: 0x00000001
Current DC Power Setting Index: 0x00000001
Say I want to extract the AC value for Allow hybrid sleep
, which in this case is 0x00000001
. 假设我要提取“ Allow hybrid sleep
的AC值,在这种情况下为0x00000001
。 I have the setting_guid
available to be interposed into the query string. 我可以将setting_guid
插入查询字符串中。
For now I am using this piece of code to dynamically extract the value of a specific setting: 现在,我正在使用这段代码来动态提取特定设置的值:
$block = powercfg /q #{scheme_guid} #{sub_guid}
$setting = $block | Select-String -Pattern #{setting_guid} -Context 0, 8 | %{$_.Context.PostContext}
$line = $setting | Select-String -Pattern 'Current #{ac_or_dc} Power Setting Index'
$line -match 'Current #{ac_or_dc} Power Setting Index: (?<value>0x.{8})'
Write-Output ([int]$matches['value'])
This works fine for now, but the hardcoded -Context 0, 8
is not really desirable, because sometimes blocks can be really short or long and my query will fail to extract the value or it will retrieve from a wrong line. -Context 0, 8
可以正常工作,但是硬编码的-Context 0, 8
并不是真正可取的,因为有时块可能真的很短或很长,而我的查询将无法提取值或从错误的行中检索。 I hope to find a cleaner way to do this, preferably programmatic and human-readable ( regex is fine as long as it makes sense). 我希望找到一种更清洁的方式来做到这一点,最好是程序化且易于阅读(只要有意义就可以使用正则表达式 )。
If we wish to do this task with a regular expression, we might want to start with an expression that passes newlines, similar to these: 如果我们希望使用正则表达式执行此任务,则可能需要以传递换行符的表达式开始,类似于以下内容:
Allow hybrid sleep[\s\S]+?Current DC Power Setting Index:\s+(.+)\s
Allow hybrid sleep[\s\S]+?Current DC Power Setting Index:\s+(.+)
Allow hybrid sleep[\w\W]+?Current DC Power Setting Index:\s+(.+)\s
Allow hybrid sleep[\d\D]+?Current DC Power Setting Index:\s+(.+)
which our desired output would be in this capturing group: (.+)
. 我们期望的输出将在此捕获组中: (.+)
。
If this expression wasn't desired and you wish to modify it, please visit this link at regex101.com . 如果不需要此表达式,并且希望对其进行修改,请访问此链接regex101.com 。
How about this way... 这样吧...
$PowerData = @'
Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)
GUID Alias: SCHEME_BALANCED
Subgroup GUID: 238c9fa8-0aad-41ed-83f4-97be242c8f20 (Sleep)
GUID Alias: SUB_SLEEP
Power Setting GUID: 29f6c1db-86da-48c5-9fdb-f2b67b1f44da (Sleep after)
GUID Alias: STANDBYIDLE
Minimum Possible Setting: 0x00000000
Maximum Possible Setting: 0xffffffff
Possible Settings increment: 0x00000001
Possible Settings units: Seconds
Current AC Power Setting Index: 0x00000708
Current DC Power Setting Index: 0x00000384
Power Setting GUID: 94ac6d29-73ce-41a6-809f-6363ba21b47e (Allow hybrid sleep)
GUID Alias: HYBRIDSLEEP
Possible Setting Index: 000
Possible Setting Friendly Name: Off
Possible Setting Index: 001
Possible Setting Friendly Name: On
Current AC Power Setting Index: 0x00000001
Current DC Power Setting Index: 0x00000001
Power Setting GUID: 9d7815a6-7ee4-497e-8888-515a05f02364 (Hibernate after)
GUID Alias: HIBERNATEIDLE
Minimum Possible Setting: 0x00000000
Maximum Possible Setting: 0xffffffff
Possible Settings increment: 0x00000001
Possible Settings units: Seconds
Current AC Power Setting Index: 0x00002a30
Current DC Power Setting Index: 0x00002a30
Power Setting GUID: bd3b718a-0680-4d9d-8ab2-e1d2b4ac806d (Allow wake timers)
GUID Alias: RTCWAKE
Possible Setting Index: 000
Possible Setting Friendly Name: Disable
Possible Setting Index: 001
Possible Setting Friendly Name: Enable
Possible Setting Index: 002
Possible Setting Friendly Name: Important Wake Timers Only
Current AC Power Setting Index: 0x00000001
Current DC Power Setting Index: 0x00000001
'@
[regex]::Matches($PowerData,'(?s)hybrid.*?DC').Value |
ForEach {[regex]::Matches($PSitem,'Current AC Power Setting Index.*').Value}
# Results
Current AC Power Setting Index: 0x00000001
Or 要么
Clear-Host; (((Get-Content -Path '.\PowerDataTemplate.txt')) -match 'hybrid|AC')#[3]
<#
Current AC Power Setting Index: 0x00000708
Power Setting GUID: 94ac6d29-73ce-41a6-809f-6363ba21b47e (Allow hybrid sleep)
GUID Alias: HYBRIDSLEEP
Current AC Power Setting Index: 0x00000001
Current AC Power Setting Index: 0x00002a30
Power Setting GUID: bd3b718a-0680-4d9d-8ab2-e1d2b4ac806d (Allow wake timers)
Current AC Power Setting Index: 0x00000001
#>
Clear-Host; (((Get-Content -Path '.\PowerDataTemplate.txt')) -match 'hybrid|AC')[3]
# Current AC Power Setting Index: 0x00000001
Clear-Host; [regex]::matches($(Get-Content -Path 'variable:\PowerData'),'.*hybrid.*|.*AC.*').Value
<#
Current AC Power Setting Index: 0x00000708
Power Setting GUID: 94ac6d29-73ce-41a6-809f-6363ba21b47e (Allow hybrid sleep)
Current AC Power Setting Index: 0x00000001
Current AC Power Setting Index: 0x00002a30
Current AC Power Setting Index: 0x00000001
#>
Clear-Host; [regex]::matches($(Get-Content -Path 'variable:\PowerData'),'.*hybrid.*|.*AC.*').Value[2]
# Current AC Power Setting Index: 0x00000001
Or in PowerShellv5x, you can use the ConvertFrom-String or ConvertFrom-StringData cmdlets using string conversion templates. 或者在PowerShellv5x中,可以使用具有字符串转换模板的ConvertFrom-String或ConvertFrom-StringData cmdlet。
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertfrom-stringdata?view=powershell-6 https://docs.microsoft.com/zh-cn/powershell/module/microsoft.powershell.utility/convertfrom-stringdata?view=powershell-6
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertfrom-string?view=powershell-5.1 https://docs.microsoft.com/zh-cn/powershell/module/microsoft.powershell.utility/convertfrom-string?view=powershell-5.1
Update for OP 更新OP
I though about this a bit more, and if all you are after is a particular settings, then why not directly ask for it. 我对此进行了更多介绍,如果您所追求的只是一个特定的设置,那为什么不直接要求它呢。 For Example. 例如。
# Get only (Allow hybrid sleep)
powercfg.exe query SCHEME_MIN SUB_SLEEP HYBRIDSLEEP
# Get only the AC setting
(powercfg.exe query SCHEME_MIN SUB_SLEEP HYBRIDSLEEP) -match 'Current AC Power Setting Index'
# Results
Current AC Power Setting Index: 0x00000000
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.