none
Parsing a string in powershell RRS feed

  • Question

  • I've looked around a bit and can't quite find an answer to this.    I've got a script going that looks at a configuration file, and I need to find the values that is inside of quotes.   

    config file:

    Version = "3.2"

    currently in my script I simply have

    $Versionvalue = get-content $ConfigFile | select-string "Version"     

    However this returns the whole string and I need just the number that is in quotes, in Unix I would do this with some cut commands, but I haven't quite found the equivalent in my searches. 

    Thanks in advance

    Thursday, January 2, 2014 5:49 PM

Answers

  • You need to use parenthesis to do capturing. You can do numbered captures, or named captures. This looks like a fairly simple regular expression, so numbered is fine.

    Here are two examples using both numbered and named captures with Select-String. This assumes your version is always 'Major.Minor'. If you have revision or build numbers in there (even if they're optional), you'll need to modify the regex. (I don't use select-string very much, so there might be a better way to do this):

    # Numbered
    Get-Item $ConfigFile | Select-String -pattern 'Version = "(\d+\.\d+)"' | select -exp matches | % { $_.groups[1].Value }
    
    # Named
    Get-Item $ConfigFile | Select-String -pattern 'Version = "(?<version>\d+\.\d+)"' | select -exp matches | % { $_.groups["version"].Value }
    

    Here's how I would do it using the -match comparison operator (which doesn't mean it's the best way). For more info on the -match operator, see the about_Comparison_Operators help topic:

    # Numbered:
    Get-Content $ConfigFile | foreach { if ($_ -match 'Version = "(\d+\.\d+)"') { $matches[1] } }
    
    # Named:
    Get-Content $ConfigFile | foreach { if ($_ -match 'Version = "(?<version>\d+\.\d+)"') { $matches.version } }
    

    Note that if your config file has more than one 'Version = "x.x"' line in it, you'll get more than one result back.

    • Marked as answer by Canty B Thursday, January 2, 2014 7:27 PM
    Thursday, January 2, 2014 6:27 PM

All replies

  • You need to use parenthesis to do capturing. You can do numbered captures, or named captures. This looks like a fairly simple regular expression, so numbered is fine.

    Here are two examples using both numbered and named captures with Select-String. This assumes your version is always 'Major.Minor'. If you have revision or build numbers in there (even if they're optional), you'll need to modify the regex. (I don't use select-string very much, so there might be a better way to do this):

    # Numbered
    Get-Item $ConfigFile | Select-String -pattern 'Version = "(\d+\.\d+)"' | select -exp matches | % { $_.groups[1].Value }
    
    # Named
    Get-Item $ConfigFile | Select-String -pattern 'Version = "(?<version>\d+\.\d+)"' | select -exp matches | % { $_.groups["version"].Value }
    

    Here's how I would do it using the -match comparison operator (which doesn't mean it's the best way). For more info on the -match operator, see the about_Comparison_Operators help topic:

    # Numbered:
    Get-Content $ConfigFile | foreach { if ($_ -match 'Version = "(\d+\.\d+)"') { $matches[1] } }
    
    # Named:
    Get-Content $ConfigFile | foreach { if ($_ -match 'Version = "(?<version>\d+\.\d+)"') { $matches.version } }
    

    Note that if your config file has more than one 'Version = "x.x"' line in it, you'll get more than one result back.

    • Marked as answer by Canty B Thursday, January 2, 2014 7:27 PM
    Thursday, January 2, 2014 6:27 PM
  • Thank you for your explanation and your examples!  I was able to follow the code between each pipe and it makes sense now the method of parsing out the string in powershell.      Thanks again! 
    Thursday, January 2, 2014 7:34 PM