Search code examples
arraysstringpowershellmerge

Combine Multilines in one element of array


I have part of switch config include all interface ethernet port configuration.

Interface Ethernet1/0/12
 switchport mode hybrid
 switchport hybrid allowed vlan 21-29 untag
 switchport hybrid native vlan 21
 mac-authentication-bypass enable
 mac-authentication-bypass guest-vlan 21
Interface Ethernet1/0/13
 switchport mode hybrid
 switchport hybrid allowed vlan 21-29 untag
 switchport hybrid native vlan 21
 mac-authentication-bypass enable
 mac-authentication-bypass guest-vlan 21
Interface Ethernet1/0/14
 switchport mode hybrid
 switchport hybrid allowed vlan 21-29 untag
 switchport hybrid native vlan 21
 mac-authentication-bypass enable
 mac-authentication-bypass guest-vlan 21
Interface Ethernet1/0/15
 switchport mode hybrid
 switchport hybrid allowed vlan 21-29 untag
 switchport hybrid native vlan 21
 mac-authentication-bypass enable
 mac-authentication-bypass guest-vlan 21

I need to convert each block like this:

Interface Ethernet1/0/12
 switchport mode hybrid
 switchport hybrid allowed vlan 21-29 untag
 switchport hybrid native vlan 21
 mac-authentication-bypass enable
 mac-authentication-bypass guest-vlan 21

into element of array.

The count rows below "Interface Ethernet1/0/12" can be difference

Can you show me example how can do it?


Solution

  • The simplest solution is to use -split, the string splitting operator with a regex that splits at each newline (\r?\n) that is followed by a non-whitespace character (\S):

    $arrayWithBlocksOfLines = 
      (Get-Content -Raw file.txt) -split '\r?\n(?=\S|$)' -ne ''
    

    Tip of the hat to Mathias R. Jessen for suggesting that the regex consume the newlines between blocks, so that they don't become part of the array elements.

    • The above assumes a file as input; if the text to process is in a variable in memory, replace (Get-Content ...) with a reference to that variable.

    • For an explanation of the regex and the option to experiment with it, see this regex101.com page, but in short:

      • \r?\n is a cross-platform pattern for matching a single newline.
      • (?=…) is a positive lookahead assertion that looks for a pattern without capturing it as part of a match; that pattern is \S, a non-whitespace character or (|) $, the end of the input string (the latter ensures that a trailing newline at the end of the input is consumed too).
    • Finally, -ne '' filters out the empty array element that results from the splitting regex matching at the end of the input if it has a trailing newline.