using Powershell, how can I find a specific line in a multi-line variable, then locate the 3rd word or value within the line

17,212

Solution 1

Firmware = ($Status | Select-String -Pattern '\d{1}\.\d{1,2}\.\d{1,2}' -AllMatches | % { $_.Matches } | % { $_.Value }

Solution 2

$Firmware = ($Status | Select-String -Pattern '(?<=Firmware Version:\s+)[\d.]+').Matches.Value

The regular expression here is looking for 1 or more combinations of digits \d and literal dots which are preceded by the Firmware Version: line.

Note that Select-String returns an object, so we use .Matches.Value to get the actual match (which in this case will only be the number).

Solution 3

Using -replace with a multi-line regex:

$Var = 
@'
Device Number:  1
PCIe slot:  3
Firmware Version:  5.1.4
Temperature:  45C
State:  Online
'@

$Firmware = $var -replace '(?ms).+^Firmware Version:\s+([0-9.]+).+','$1'
$Firmware

5.1.4
Share:
17,212
RayD
Author by

RayD

BY DAY: I work at Western Digital as a Storage Support Engineer. BY NIGHT: I'm a father, brother, son, a gamer, and love to script in bash and python.

Updated on June 18, 2022

Comments

  • RayD
    RayD almost 2 years

    I'm using Windows 2012 powershell to scrape values from a 3rd party executable. My goal is to re-arrange and simplify the output of the tool to display only a subset of the content and allow me to collect the data on many devices at once. I have most of the script working, but I'm stuck on a simple task that's so easy in Linux bash.

    The 3rd party program is pulling status of a computer device to standard out. I can successfully set the standard out content to a variable. For example:

    PS C:\> $status = mycmd.exe device1 --status
    PS C:\> $status
    

    The $status variable would return a multi-line list of values as follows:

    Device Number:  1
    PCIe slot:  3
    Firmware Version:  5.1.4
    Temperature:  45C
    State:  Online
    

    In this case, I would like to create a new variable for the firmware version. In Linux I would use something like this (although there are many options available):

    Firmware=$(mycmd device1 --status | grep "Firmware" | cut -c 19-24)
    

    In Powershell I can use the Select-String command to can find the "firmware" pattern and set it to a varible as follows:

    $Firmware = $Status | select-string -Pattern "Firmware Version"
    

    This gives me the entire Firmware version line. I can't figure out how to substring just the version number from the line as Powershell seems to only want to manipulate the item I'm searching for and not the content next to the pattern. Since this isn't a built in command with an object name, manipulating text seems much more difficult.

    I would like the $Firmware variable to equal "5.1.4" or it could be placed into another variable if necessary.

  • Bram
    Bram almost 7 years
    The purpose of the '(?ms) in the regular expression here is explained at stackoverflow.com/questions/27680097/what-does-ms-in-regex-m‌​ean