Home > Back-end >  Construct a formatted list of strings in PowerShell
Construct a formatted list of strings in PowerShell

Time:12-02

I have several lists consisting of strings like this (imagine them as a tree of sort):

$list1:

data-pool
data-pool.house 1
data-pool.house 1.door2
data-pool.house 1.door3
data-pool.house2
data-pool.house2.door 1

To make them more easier to parse as a tree how can indent them based on how many . characters occur while ditching the repetitive text earlier in the line? For example:

data-pool
  house 1
    door2
    door3
  house2
    door 1

The way I approached it counting the occurrences of .s with .split('.').Length-1 to determine the amount of needed indents and then adding the spaces using .IndexOf('.') and .Substring(0, <position>) feels overly complicated - or then I just can't wrap my head around how to do it in a less complicated way.

CodePudding user response:

I think this should work as long as the number of nodes from line to line are ordered, what I mean by this is that it will not look "pretty" if for example the current node has n elements and the next node has n 2 or more.

To put it into perspective, using this list as an example:

$list = @'
data-pool
data-pool.house 1
data-pool.house 1.door2
data-pool.house 1.door3
data-pool.house 1.door4.something1
data-pool.house2
data-pool.house2.door 1
data-pool.house2.door 2.something1
data-pool.house2.door 3.something1.something2
data-pool.house3
data-pool.house3.door 1
data-pool.house3.door 2
'@ -split '\r?\n'

The function indent will take each line of your list and will split it using . as delimiter, if the count of elements after splitting is lower than or equal to 1 it will not perform any modification and display that line as is, else, it will multiply the $IndentType containing 2 white spaces by the number of elements of the split array minus 1 and concatenate it with the last element of the split array.

function indent {
param(
    [string]$Value,
    [string]$IndentType = '  '
)
    $out = $Value -split '\.'
    $level = $out.Count - 1

    '{0}{1}' -f ($null,($IndentType*$level))[[int]($out.Count -gt 1)], $out[-1]
}

$list.ForEach({ indent $_ })

Sample:

data-pool
  house 1
    door2
    door3
      something1
  house2
    door 1
      something1
        something2
  house3
    door 1
    door 2

CodePudding user response:

the approach to get the last element of the string is below

## String
$string = "data-pool.house 1"
## split the string into an array every "."
$split = $string.split(".")
## return the last element of the array
write-host $split[-1] -ForegroundColor Green

Then to test against each string

$myArray = ("data-pool", "data-pool.house 1", "data-pool.house 1.door2", "data-pool.house 1.door3", "data-pool.house2", "data-pool.house2.door 1")
ForEach($Name in $myArray) {
    ## String
    $Name = $Name.ToString()
    $string = $Name
    $split = $string.split(".")
    ## return the last element of the array
    write-host $split[-1] -ForegroundColor Green
}
  • Related