Powershell: Working with strings – Data Manipulation


In my first post, PowerShell: Working with Strings I talked about the types of strings and how to make them. Now lets talk about how to manipulate that data.

What it comes down to is one of two types of string data. It’s either a single string, or a collection of strings. Get-Content returns a collection of strings as do many other cmdlets and most cmd programs (ipconfig)  so we are going to work with these two sets.


$str1 = "hello world!"

$str2 = "hello","world"

The $str2 is just a way to simulate what Get-Content would give us.

First, lets start by looking to see what we can do with a basic string:


$str1 | gm

You’ll notice you have a System.String object and a bunch of methods to work with. One thing to keep in mind about a String is that its immutable which basically means you can’t change the value of the variable, you’ll need to store it to a new variable with the new value you want. Lets try to change our basic string to upper case:


$str1.ToUpper()

$str1

You’ll notice when we just type $str1 its back to lower case (ie, immutable).  So if we wanted to keep that we’d need to store it some place, but lets keep it as it is.

Looking at my original string you’ll see its all lower case, so lets change that h to an H. There are a few ways we can do it, and since we only have one H in this string, we have even more options. Most of these are a bit over kill, but they allow me to show an assortment of methods.


#simple replace

$str1.replace("h","H")

#sub string grabs from index to end in this case

#we just slap an H in front, good if there are multiple h's

"H" + $str1.substring(1)

"H$($str1.substring(1))"

#now in to the over kill

$str1.Insert(0,"H").Remove(1,1)

$str1.Remove($str1.IndexOf("h"),1).Insert(0,"h")

There are a few neat things to note here, the first being tacking on to methods.

$object.method().method().method() and so on

Which would work something like this

(($object.method()).method()).method()

Too many parentheses to follow? The point is, as you tack them on the new method works on the result of the previous, in our case it’s always a string, but that could change depending on what you are doing.

Another thing is the nesting of methods which can be handy, but some times harder to follow, in a script, it usually worth while to add a few extra characters to make it readable.

As you noticed when you did the Get-Member (shorthand gm) on the string, there were a lot of methods and it had the definition for each but most were packed in and it was hard to read, so if you are curious you can go to MSDN or you can type a method in without the () like so:


$str1.substring

Doing so will spit out something like this:

OverloadDefinitions

——————-

string Substring(int startIndex)

string Substring(int startIndex, int length)

Which shows the different ways to call the method. The first item is the return type, in both cases here it’s a string. Then it shows the name of the method and its param options. We have two cases here, a StartIndex and a StartIndex and Length. In the first case we provided a starting point and it goes to the end of the string, in the next case we provide a starting point and a distance.


$str1.substring(6)

$str1.substring(6,5)



So far everything we've been doing is .NET methods from the String object but PowerShell has some neat ways to handle this as well.



$str1 -replace "h", "H"

This works just as well but there a two very important notes here the first being that the .NET methods are case-sensitive and PowerShell is not, try this:


$str1 -replace "E", "h"

$str1.replace("E","h")

In the first case the e was replaced and in the second it was not.

The other thing to keep in mind is that many of the PowerShell comparison operators use regular expressions rather than just simple character replacement as the .NET methods do. I’ll go in to RegEx and the different operators in my next post on strings.

Now, I mentioned two types of string data and really only talked about one. The reason I made mention of both is so that you don’t try to do these operations on the return of a get-content or on the output of a command app.

One Thing I would like to point out is the Length property on our objects $str1 and $str2.


$str1.length

$str2.length

$str2[0].length

You’ll notice that the return on $str2.lenth is 2, which is how many items are in the array. This may seem obvious now, but when working with PowerShell you may not always know ahead of time if it’s an array or not (Another post on arrays some day.)

If however you have data like that and would like to make it a single string, you can do so with Join. Again you have the .NET and PowerShell way to do this.


$str2 -join " "

[string]::join(" ",$str2)

You’re probably wondering where the [string]::join came from. That’s a static method on the String class that was not listed by the gm we did before. If you looked at the MSDN docs you’ll see some methods with an S next to them, indicating they are static, but, who wants to leave PowerShell?


gm -i $str1 -Static

Thankfully the Get-Member cmdlet has a Static param that will show us the static methods available to an object of that type! Have I mentioned before how much I love Get-Member?

There is a ton more that can be done with strings but, I hope this enough to allow you to dig in to it more on your own!

Until next time (RegEx!)

Advertisements

About jrich

I am the Solutions Architect for Apex Learning in Seattle WA. I've been working with computers since I was 13. Started programming when I was 14. Had my first IT job as tech support at an ISP at the age of 15 and became a network admin at the age of 17. Since then I've worked at a variety of small to mid size companies supporting, maintaining and developing all aspects of IT. Mostly working with Windows based networks but have recently been working with Solaris system as well. I created this blog mostly as a place for me to take my own notes, but also share things that I had a hard time finding the info for.

Posted on December 21, 2011, in Uncategorized, WMF (Powershell/WinRM) and tagged , , , , , . Bookmark the permalink. 2 Comments.

  1. Nice article, but one quibble. Not all the comparison operators use regular expressions. The -like operator uses wildcard matches, and I’ve seen this cause some confusion when someone tries something like “hello world” -like “hello” and don’t get the results they’re expecting.

  2. Thats a great point, the difference between -like and -match
    I didnt want to go in to detail on every operator because then I’d have writen a book (which I’ll do some day) but I more so wanted to lead people in the right direction enabling them to figure these things out themselves. However I find that sentence to be misleading and I’ll rework that. Thanks for the feedback!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: