Blog Archives

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!)

Powershell: Working with Strings – The basics


$name = “Justin”
$date = get-date
#### all double quotes – variables evaluated
## old style concat

“hello ” +  $name + “, how are you this ” + $date.dayofweek
## powershell way, my favorite
“hello $name, how are you this $($date.dayofweek)”
## .net formatting, can be very useful.
“hello {0}, how are you this {1}” -f $name,$date.dayofweek
## static method of string class
[string]::Concat(“hello “, $name, “, how are you this “, $date.dayofweek)
## here-string – these are cool!
@”
hello $name
how are you this $($date.dayofweek)
“@##### single quotes – variables are NOT evaluated in quotes
‘hello ‘ +  $name + ‘, how are you this ‘ + $date.dayofweek
‘hello $name, how are you this $($date.dayofweek)’
‘hello {0}, how are you this {1}’ -f $name,$date.dayofweek
[string]::Concat(‘hello ‘, $name, ‘, how are you this ‘, $date.dayofweek)@’
hello $name
how are you this $($date.dayofweek)
‘@

Powershell has a lot of great ways to work with text and one of my favorite ways is inline. If you have a string with a variable in it that variable will be evaluated as show above with

“hello $name, how are you this $($date.DayOfWeek)”

The output of this is:

hello Justin, how are you this Friday

I didn’t need to do anything special to make this work, and as you can imagine with building larger strings, this can be very helpful. Speaking of larger strings, lets jump down to the Here-String, another great feature of Powershell.

@”
hello $name
how are you this $($date.dayofweek)
“@

To start a Here-String you must end the line with @”, and to end it, the line must start with “@ (Thanks Larry).

whatever…. @”    <end of line here>
content of here string in here….
<start of line> @” whatever…..

Great for building email bodies or the such.

Single Quote Vs. Double Quote

The top section of code uses all double quotes, and you’ll notice that the variables are evaluated with in those quotes, where as on the bottom it’s a literal string, meaning nothing is evaluated with in the quotes.

How Evaluation works

There is one thing to keep in mind when evaluating variables with members. As you can see in the code we have two variables, a basic String and a DateTime object. With the string I just use the variable inline and it evaluates, but with the DateTime object I have to wrap it to access a member item, otherwise it evaluates just the $Date.

“$($date.DayOfWeek)”
“$date.DayOfWeek”

You’ll notice the difference in the output,

Friday
07/01/2011 09:16:31.DayOfWeek

$() evaluates the expression inside of the () before writing it, so you can use it to access members but you can also use it to do other things.

“2 + 3 = $(2+3)”

String Format

You can even use the string Format to display info which is like the old C/C++ way. Normally I wouldn’t bother with this method, but it’s great with numbers and dates.

http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx

“{0}” –f $date

“{0:MM-yy}” –f $date

Great for building dates for use with filenames. There are 3 parts to the Format Item syntax

{index[,alignment][:formatstring]}

This is also good for building tables. lets say you have a first and last time and you want them to line up well, you can specify the size of the field (using negative for left alignment).

“-{0,15}-” -f $name
“-{0,-15}-” -f $name

Cool huh?

More info here

http://msdn.microsoft.com/en-us/library/txafckwd.aspx

A Bonus – Static Members

I’m such a big fan of Get-Member that I have to mention it as much as I can. You’ll notice at the top there is a line for Concat. Would I ever use this? Pretty unlikely, But it shows something cool, Static Member’s.

Get-Member –inputobject “” –Static

This will give you a Strings Static members. We can use Static Members like so

[Class]::StaticMember

[Net.Dns]::GetHostEntry($computer)

Note: System. is assumed in class references!

Hope this helps!

Second Installment!

Design a site like this with WordPress.com
Get started