Merge lines from table/string

This topic contains 3 replies, has 2 voices, and was last updated by Profile photo of Craig Duff Craig Duff 4 months, 1 week ago.

  • Author
    Posts
  • #49161
    Profile photo of Rusty_uk
    Rusty_uk
    Participant

    Hi

    Im stuck on something that i hope you guys can help with. Im trying to convert some markdown tables from grid to piped (since my wiki does not understand grid tables). The issue im having is with the table headings. My wiki will not recognise multiline headings so i need to convert the lines in the heading into a single line. The kicker is that i will not know how many rows are in the table. An example is as follows.

    +————————————–+————————————–+
    | Library folder | Library\\TP thing\\Subflows |
    | | \\Thisfdf Base |
    +======================================+======================================+
    | Description | This Generic thing will get the User |
    | | dfdfdsfsdf, Rodf dsfsdffdf ID, |
    | | dffdfffdfD, dffdfdfff and the |
    | | adsaddfwewqewqee by calling the |
    | | required www wee and returning them |
    | | as weewew wewt variables. |
    +————————————–+————————————–+
    | Inputs | – hhh\hh\yyyytt |
    | | |
    | | – HYG\JDNDUBJBJSDDD\JJJ |
    +————————————–+————————————–+

    I just need to merge the first lines before the +======+ line so that it becomes more like the following.

    +————————————–+————————————–+
    | Library folder | Library\\TP thing\\Subflows \\Thisfdf Base |
    +======================================+======================================+
    | Description | This Generic thing will get the User |
    | | dfdfdsfsdf, Rodf dsfsdffdf ID, |
    | | dffdfffdfD, dffdfdfff and the |

    Any ideas guys?

    Thanks

    R

    • This topic was modified 4 months, 1 week ago by Profile photo of Rusty_uk Rusty_uk.
  • #49166
    Profile photo of Craig Duff
    Craig Duff
    Participant

    I actually did something very similar last week: parsing output from netsh for PS2 Win 7 computers to collect firewall rule that have been manually defined. Some of the output of netsh were on multiple lines. Basically, I used a field variable, and when it hit certain patters it either appends data to it or flushes it out.

    Function Get-NetshAdvFirewallRules
    {
        Begin
        {
            $command = "netsh.exe advfirewall firewall show rule name=all verbose"
            $array = New-Object -TypeName System.Collections.ArrayList
        }
    
        Process
        {
            $results = Invoke-Expression -Command $command
    
            $props = @{}
    
            For ($i = 0; $i -lt $results.Count; $i++) 
            {
                $line = $results[$i].Trim()
    
                If( -not $line -and $props.Keys.Count ) 
                {
                    $array.Add( ( New-Object -TypeName PSObject -Property $props ) ) |
                    Out-Null
                    $props = @{}
                    Clear-Variable -Name 'field'
                    Continue
                }
                ElseIf( $line.StartsWith('-') -or $line.StartsWith('Ok') )
                {
                    Clear-Variable 'field'
                    Continue
                }
                ElseIf ( $line -match '^(?.*?):\s*(?.*?)$' )
                {
                    $field = $Matches['name'].Trim()
                    $props[$field] = $Matches['value'].Trim()
                }
                ElseIf ( $field )
                {
                    $props[$field] += " \\ $line"
                }
            }
    
            If( $props.Count )
            {
                $array.Add( ( New-Object -TypeName PSObject -Property $props ) ) |
                Out-Null
            }
    
            $array | Write-Output
        } 
    } # Function Get-NetshAdvFirewallRules
    • This reply was modified 4 months, 1 week ago by Profile photo of Craig Duff Craig Duff.
  • #49178
    Profile photo of Rusty_uk
    Rusty_uk
    Participant

    Thanks for that Craig. The issue i have though is that this is "|" delimited so i would have to add the text in pipe location 2 to the same pipe location. If you get what i mean ??

  • #49180
    Profile photo of Craig Duff
    Craig Duff
    Participant
    $simulate_read = @"
    +————————————–+————————————–+
    | Library folder | Library\\TP thing\\Subflows |
    | | \\Thisfdf Base |
    +======================================+======================================+
    | Description | This Generic thing will get the User |
    | | dfdfdsfsdf, Rodf dsfsdffdf ID, |
    | | dffdfffdfD, dffdfdfff and the |
    | | adsaddfwewqewqee by calling the |
    | | required www wee and returning them |
    | | as weewew wewt variables. |
    +————————————–+————————————–+
    | Inputs | – hhh\hh\yyyytt |
    | | |
    | | – HYG\JDNDUBJBJSDDD\JJJ |
    +————————————–+————————————–+
    "@ -split "`r`n"
    
    $header_sections = @(
        'Header'
        'Footer'
        'Closed'
    )
    
    $section = ''
    $header_cnt = 0
    
    $Out = @()
    
    ForEach ($line in $simulate_read)
    {
    
        If($line -match '^\+—+')
        {
            $section = $header_sections[($header_cnt++)]
            If($header_data)
            {
                Clear-Variable -Name 'header_data'
            }
            $out += $line
        }
        ElseIf ($line -match '^\+=+')
        {
            $section = 'Data'
            If(-not $header_cnt) 
            { 
                $header_cnt += 1 
            }
    
            IF($header_data)
            {
                $out += "|$($header_data -join '|')|"
                Clear-Variable -Name 'header_data'
            }
            $out += $line
        }
        ElseIf ($line -match '^\|')
        {
            If (-not $section) { 
                $section = 'Data'
                If(-not $header_cnt)
                {
                    $header_cnt += 1
                }
            }
    
            Switch($section)
            {
                'Header'
                {
                    $new = $line.Trim().split('|')
                    $new = $new[1..($new.Length - 2)]
                    If(-not $header_data)
                    {
                        $header_data = $new
                    }
                    Else
                    {
                        For($i=0;$i -lt $new.count;$i++)
                        {
                            $header_data[$i] += $new[$i].Trim()
                        }
                    }
                }
    
                'Data'
                {
                    $out += $line
                }
    
                'Footer'
                {
                    $out += $line
                }
    
                Default
                {
                    $out += $line
                }
            }
        }
    
    }
    
    $out

    There's a start. Not sure I'm happy with it, but basic idea is to keep track of where you are as far as the table section and apply different processing rules according to the section. You can then use split to break down the fields by pipe turning that into an array to which you can add the values from subsequent lines.

You must be logged in to reply to this topic.