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:
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
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:
Doing so will spit out something like this:
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.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!)