如何在Powershell中已匹配的行之后选择第一条匹配的行?

时间:2019-06-07 23:10:02

标签: regex windows powershell chef powercfg

我正在尝试使用 powershell powercfg的输出中查询某些Windows电源设置。我有足够的信息来将范围缩小到设置的子组,但是在文本块中,我仍然需要使用GUID查找匹配的设置,然后需要提取该设置的当前设置值。我可以使用Select-String -Context来实现这一点,但是它不是动态的,因此容易出错。我正在寻找一种更干净的方法来提取价值。

这是我拥有的文本块的一个示例(存储在$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

说我想提取Allow hybrid sleep的AC值,在这种情况下为0x00000001。我有setting_guid可插入查询字符串。

目前,我正在使用这段代码来动态提取特定设置的值:

$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'])

这现在可以正常工作,但是硬编码的-Context 0, 8并不是很理想,因为有时块可能真的很短或很长,而且我的查询将无法提取值或从错误的行中检索。 我希望找到一种更清洁的方式来做到这一点,最好是程序化且易于阅读(只要合理就可以使用 regex )。

2 个答案:

答案 0 :(得分:0)

如果我们希望使用正则表达式执行此任务,则可能需要以传递换行符的表达式开始,类似于以下内容:

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+(.+)

我们期望的输出将在以下捕获组中:(.+)

Demo

RegEx

如果不需要此表达式,并且希望对其进行修改,请访问regex101.com上的此链接。

RegEx电路

jex.im可视化正则表达式:

enter image description here

答案 1 :(得分:0)

这种方式...

$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

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

或者在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/en-us/powershell/module/microsoft.powershell.utility/convertfrom-string?view=powershell-5.1

OP更新

我对此进行了更多介绍,如果您所追求的只是一个特定的设置,那为什么不直接要求它。例如。

# 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