Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell split string into two dimensional array

TL:DR

Using PowerShell I want to split a string of text first by the new line character (\n), store it into an array, then split those array entries with a comma into a two-dimensional array. I am having trouble accessing (or possibly creating) any information in the second dimension.

INFO:

I have the following string (stored as $services):

SUPER-PC,Microsoft Office ClickToRun Service,ClickToRunSvc,C:\Program Files\Microsoft Office 15\ClientX64\OfficeClickToRun.exe /service,Auto
SUPER-PC,Adobe Acrobat Update Service,AdobeARMservice,C:\Program Files (x86)\Common Files\Adobe\ARM\1.0\armsvc.exe,Auto

Desired result:

I want to split the string twice:

  1. Split on the new line (first dimension)
  2. Split on the commas within the line (second dimension)

I want the end result of this to be a two dimensional array that I can reference. (Ex: $services[0][0] etc.)

Commands Used:

To accomplish the new line split I have been using the following command:

$services= $services -split "\n"

To access the split string in the new array structure I can do the following:

$services[0]

PowerShell displays only the first line of $services

Next I use:

$services[0] = $services[0] -split ','

Problem:

When I attempt to access the second dimension of the first array using $services[0][0] it displays S which is the first character of the character array ("SUPER-PC" being the start of the string), not the two-dimensional array I want to create.

Where am I going wrong?

like image 508
Shrout1 Avatar asked Oct 22 '25 13:10

Shrout1


2 Answers

-split returns an object of type string[], meaning that you can't assign anything other than a string to a single item without changing the type of the entire array.

What happens instead, when the parser sees that you're trying to assign a new array to one of the items in the existing $services string array, it automatically converts the new array to a string, concatenated by $OFS. Since $OFS defaults to a space, you essentially turn this string:

SUPER-PC,Microsoft Office ClickToRun Service,ClickToRunSvc,C:\Program Files\Microsoft Office 15\ClientX64\OfficeClickToRun.exe /service,Auto

into this string:

SUPER-PC Microsoft Office ClickToRun Service ClickToRunSvc C:\Program Files\Microsoft Office 15\ClientX64\OfficeClickToRun.exe /service Auto

Instead, create an entirely new array to hold the resulting arrays:

$Services = @'
SUPER-PC,Microsoft Office ClickToRun Service,ClickToRunSvc,C:\Program Files\Microsoft Office 15\ClientX64\OfficeClickToRun.exe /service,Auto
SUPER-PC,Adobe Acrobat Update Service,AdobeARMservice,C:\Program Files (x86)\Common Files\Adobe\ARM\1.0\armsvc.exe,Auto
'@

# I prefer a more OS-agnostic newline pattern
$Services = $Services -split "`r?`n"

# Create a new array, defaults to Object[], so can contain arrays as well
$MultiDimensionalServices = @()

# Iterate over each string in $Services
foreach($ServiceString in $Services){
    # use the unary array operator (,) to avoid flattening the array
    $MultiDimensionalServices += ,@($ServiceString -split ',')
}
like image 142
Mathias R. Jessen Avatar answered Oct 24 '25 07:10

Mathias R. Jessen


Is there some reason you're not doing something like this:

$ConvertedServices = $Services | ConvertFrom-Csv -Header 'ComputerName','ServiceDescription','ServiceName','CommandLine','StartUp'

And then:

$ConvertedServices[0].ComputerName

Multidimensional arrays in PowerShell do work, but they're kind of flaky to work with, IMX, especially with strings because strings are often treated as character arrays like you're experiencing here.

like image 23
Bacon Bits Avatar answered Oct 24 '25 05:10

Bacon Bits



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!