Text parsing in Powershell: Identify a target line and parse the next X lines to create objects

16,160

As you say, I think you're thinking too much foreach when you should be thinking for. The below modification should be more along the lines of what you're looking for:

$snaps = get-content C:\powershell\snaplist.txt
$snapObjects = @()

for ($i = 0; $i -lt $snaps.length; $i++)
    {
        if ([regex]::ismatch($snaps[$i],"SnapView logical unit name"))
        {
            $snapObject = new-object system.Management.Automation.PSObject
            $snapObject | add-member -membertype noteproperty -name "SnapName" -value ($snaps[$i]).replace("SnapView logical unit name:  ","")
            # $snaps[$i+1] Go to the next line and add the UID
            # $snaps[$i+2] Go to the next line and add the TLU
            # $snaps[$i+3] Go to the next line and add the State
            $snapObjects += $snapObject
        }
}

A while loop may be even cleaner because then you can increment $i by 4 instead of 1 when you hit this case, but since the other 3 lines won't trigger the "if" statement... there's no danger, just a few wasted cycles.

Share:
16,160
Formica
Author by

Formica

Updated on June 04, 2022

Comments

  • Formica
    Formica almost 2 years

    I am parsing text output from a disk array that lists information about LUN snapshots in a predictable format. After trying every other way to get this data out of the array in a useable manner, the only thing I can do is generate this text file and parse it. The output looks like this:

    SnapView logical unit name:  deleted_for_security_reasons
    SnapView logical unit ID:  60:06:01:60:52:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
    Target Logical Unit:  291
    State:  Inactive
    

    This repeats all through the file with one line break between each group. I want to identify a group, parse each of the four lines, create a new PSObject, add the value for each line as a new NoteProperty, and then add the new object to a collection.

    What I can figure out is, once I identify the first line in the block of four lines, how to then process the text from lines two, three, and four. I'm looping through each line, finding the start of a block, and then processing it. Here's what I have so far, with comments where the magic goes:

    $snaps = get-content C:\powershell\snaplist.txt
    $snapObjects = @()
    
    foreach ($line in $snaps)
        {
    
            if ([regex]::ismatch($line,"SnapView logical unit name"))
            {
                $snapObject = new-object system.Management.Automation.PSObject
                $snapObject | add-member -membertype noteproperty -name "SnapName" -value $line.replace("SnapView logical unit name:  ","")
                #Go to the next line and add the UID
                #Go to the next line and add the TLU
                #Go to the next line and add the State
                $snapObjects += $snapObject
            }
    }
    

    I have scoured the Google and StackOverflow attempting to figure out how I can reference the line number of the object I'm iterating through, and I can't figure it out. I may rely on foreach loops too much and so that's affecting my thinking, I don't know.