Spliting only a part of a text using space as a delimiter

by vandreytrindade at 2012-12-11 04:31:28

Hi,

I’ll try to write what I’m needing to do…

Suppose, I have a CSV file with one column called "FullName".

Ex.:
FullName
John Malkovich
Angelina Jolie
Matthew Perryman Jones

When I import that CSV to PowerShell, I can do stuff like:

$CSVfile = Import-Csv C:\fullnames.csv
$CSVfile | ForEach-Object {$.fullname}

So I’ll get:

John Malkovich
Angelina Jolie
Matthew Perryman Jones


Ok, but now I want to split that text using the "space" as a delimiter character to get the First Name and the Surname of each Full name.
Something like this:

$CSVfile = Import-Csv C:\fullnames.csv
$CSVfile | ForEach-Object {"Full name: "+$
.fullname+" First name: "+$.fullname.remove(5,10)+" Surname: "+$.fullname.remove(0,4)}

The ‘.remove(" "," ")’ option is only to show one example. Of course it didn’t helps what I need to do.

In other words, I need a way to split the "first name" and the "surname" from the "fullname" values.
And, like my example names shows, some names are bigger than others, so I wanted to use the "first space" in the text value to split one from another…

Confusing?
Sorry for my english.
by nohandle at 2012-12-11 05:41:06
use the -split operator
"Matthew Perryman Jones" -split " "to split this in three parts.
To split it only to only two parts and make sure the text after the split operator is not interpreted as regular expression (does not matter in case of space but matters when you want to split by . or | for exmple) use also the simple match splitting option.
"Matthew Perryman Jones" -split " ",2,"simplematch"
in cunjunction with array of variables to assign to you can save the first half to $name and the second to $surname variable:
$name,$surname="Matthew Perryman Jones" -split " ",2,"simplematch"
"name is: $name"
"surname is: $surname"
by nohandle at 2012-12-11 06:04:58
#create the collection of objets to test on
$testObjects = "John Malkovich","Angelina Jolie","Matthew Perryman Jones" |
foreach-Object {New-Object -TypeName psObject |
Add-Member -Name FullName -MemberType NoteProperty -Value $_ -PassThru}
#output the collection to review it
#$testObjects

<#now apply what has been shown in the previous example
in conjunction with the select-object to create collection with the
desired properties#>
$testObjects |
select-object @{n="FirstName";E={($.fullname -split " ",2,"simplematch")[0]}},
@{name="LastName";Expression={($
.fullname -split " ",2,"simplematch")[1]}}

basically what you do here is piping the collection testObjects to pipeline and selecting properties to show
by the select object. Select object accepts array of properties to show.
If you provide hashtable @{} that contains two pairs to the select object commandlet it
adds new property on the object.
The pairs are name (or ‘n’) and expression (or ‘e’), the name become the name of the property and
th eexpression calculates the value, in this case i take the object currently in the pipeline ($)
take its fullnameproperty, split it to two parts by the first " " and output only the first (indexed from 0)
part.
The second hashtable does the same but it output the second part (index 1 whan indexing from 0).
the hashtables are joined to array by the comma (,).

the Fullname property although used in the expression is not passed down the pipeline because it is not named in
the select-object.
The properties are add to synthetic object that is passed down the pipeline, th eoriginal object is not affected.
by vandreytrindade at 2012-12-11 06:21:29
Hi nohandle,

Thank you so much for the help!

But now I’m trying to use it in my code:

Import-Module ActiveDirectory
$CSVfile = Import-Csv "C:\ADusers.csv"
$CSVfile | ForEach-Object {New-ADUser $
.exhibition -UserPrincipalName $.upn -SamAccountName $.account -GivenName $.name -Surname $.surname -DisplayName $.exhibition -Path $.adpath -HomeDrive $.drive -HomeDirectory $.directory -Enabled $true -ChangePasswordAtLogon $true -AccountPassword (ConvertTo-SecureString $.password -AsPlainText -force)}
$CSVfile | ForEach-Object {Add-ADGroupMember -Identity G_Group -Members $
.account}



How can I use two separated commands in the "ForEach-Object"?
Like:
Import-Module ActiveDirectory
$CSVfile = Import-Csv "C:\ADusers.csv"
$CSVfile | ForEach-Object {
First do $name,$surname=$.exhibition -split " ",2,"simplematch"
Then do New-ADUser $
.exhibition -UserPrincipalName $.upn -SamAccountName $.account -GivenName $name -Surname $surname -DisplayName $.exhibition -Path $.adpath -HomeDrive $.drive -HomeDirectory $.directory -Enabled $true -ChangePasswordAtLogon $true -AccountPassword (ConvertTo-SecureString $.password -AsPlainText -force)}

Don’t know if you got it what I want…
by nohandle at 2012-12-11 06:31:04
Just like you shown it I suppose. :slight_smile:
the foreach { command is followed by scriptblock that can contain any amount of commands separated by
new line
or; semicolon}

The variables you created in the body of the script are valid in that scope - in the region between the { } to put it simply.
by nohandle at 2012-12-11 07:18:37
four commands in this foreach
"John Smith", "Jane Smith" |
foreach-object {
$firstName, $lastName = $
-split " ",2
"the firstname is t&quot; + $firstName<br> &quot;the lastname is t" + $lastName
""
}
by vandreytrindade at 2012-12-11 07:42:04
nohandle,

Thank you so much!

I’ve managed to make it by using the commands below:

Import-Module ActiveDirectory
$CSVfile = Import-Csv C:\adusers.csv
$CSVfile | ForEach-Object {$name,$surname=$.exhibition -split " ",2,"simplematch";New-ADUser $.exhibition -UserPrincipalName ($.account.remove(0,1)+"@domain.intranet") -SamAccountName $.account.remove(0,1) -GivenName $name -Surname $surname -DisplayName $.exhibition -Path $.adpath -Office $.account -HomeDrive $.drive -HomeDirectory $.directory -Enabled $true -ChangePasswordAtLogon $true -AccountPassword (ConvertTo-SecureString $.password -AsPlainText -force)}


Thanks again for the BIG help!
by nohandle at 2012-12-11 07:45:40
You are welcome. :slight_smile:

Btw next time use the powershell button to add some powershell code to make it easier to read. :slight_smile: