Reputation: 2607
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:
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?
Upvotes: 4
Views: 5657
Reputation: 17462
try this
$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")
$ConvertedServices = $Services | ConvertFrom-String -Delimiter "," -PropertyNames 'ComputerName','ServiceDescription','ServiceName','CommandLine','StartUp'
$ConvertedServices[0].ComputerName
Upvotes: 2
Reputation: 2607
Ok I hate to self answer, but this was far more simple than I thought... Both other answers are valid, and Mathias pointed me to an obvious oversight.
$string = $string -split ","
is not the same as $string = $string.split(",")
As Mathias said:
-split
returns an object of typestring[]
, meaning that you can't assign anything other than a string to a single item without changing the type of the entire array.
So I ended up utilizing:
$services= $services.split("`r`n")
and then
$services[0]= $services[0].split(",")
I was then able to successfully access the second dimension of the multi-dimensional array using services[0][0]
Also, Bacon Bit's answer is in all likelihood better than my answer; my answer just addresses my question in the simplest possible fashion.
Upvotes: 4
Reputation: 32145
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.
Upvotes: 4
Reputation: 174465
-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 ',')
}
Upvotes: 7