Search code examples
regexpowershelltext-parsing

use Powershell substring and Regex to extract a variable number of tokens


I got help from this forum to use Powershell and Regex below

if((get-content -Raw c:\config.txt) -match '(?ms)^999.*?(?=\r?\n\S|\Z)')
{ $matches[0]} 

to successfully extract the correct info for vlan 999 unused from the config below

1    default                          active    Fa0/4, Fa0/5, Fa0/6, Fa0/7, Fa0/8
120  Camera                           active    Fa0/2
130  Student                  active    Fa0/1
100  Management                        active    
999  Unused               active    Fa0/10, Fa0/11, Fa0/12, Fa0/13, 
                                                Fa0/14, Fa0/15, Fa0/16, Fa0/17
                                                Fa0/18, Fa0/19

and then I was able to use the substring method below to extract just the ports number as

Fa0/10, Fa0/11, Fa0/12, Fa0/13, Fa0/14, Fa0/15, Fa0/16, Fa0/17 Fa0/18, Fa0/19

$Unused_VLAN = $Matches[0]
$Unused_ports = Unused_VLAN.substring (48, 77) 

my problem is I have to extract this information on multiple config files and each config file has different number of unused ports.

My question is there a better way than to use substring method to extract the unused ports because I have to specify the exact starting position and the ending position of the string to extract the ports so other config file has different number of unused ports then the substring I used didn't work.


Solution

  • A pragmatic solution that uses the unary form of PowerShell's -split operator:

    # Get the block of relevant lines as a single string.
    $unusedVlan = if ((Get-Content -raw c:\config.txt) -match '(?ms)^999.*?(?=\r?\n\S|\Z)') 
      { $Matches[0]} 
    
    # Split the string into an array of token by whitespace,
    # remove all "," instances,
    # and skip the first 3 tokens 
    # (the tokens *before* the port numbers, namely '999', 'Unused', 'active')
    # The result is an *array* of all port numbers: @( 'Fa0/10', 'Fa0/11', ... )
    $unusedPorts = (-split $unusedVlan) -replace ',' | Select-Object -Skip 3
    
    # Output the array
    $unusedPorts