Learn How to Use Switch, Regex, and PowerShell to Parse Files

Learn How to Use Switch, Regex, and PowerShell to Parse Files

  • Comments 4
  • Likes

Summary: The Scripting Wife learns how to use the Windows PowerShell switch command and regular expressions to parse text files.

Microsoft Scripting Guy, Ed Wilson, is here. The Script Week Live Meetings have been great fun, and the feedback has been incredible. The registration for the 2011 Scripting Games is going well, and it is hard to believe that the games kick off in a mere six days. Of course, if you have been putting off the registration and the preparation for the games, there is still plenty of time—one can learn an awful lot of Windows PowerShell in six days. Of course, there are also four more Script Week live meetings, and I encourage you to register for those events. The questions asked during the presentation are part of what makes the event so much fun.

I am sitting in the dining room, nodding over my laptop—I still have not fully recovered from my all-night flight from Seattle. Besides that, it is still “oh dark thirty” outside. I am debating making a cup of coffee, but I do not feel that it would help…perhaps a nice pot of English Breakfast tea would be worthwhile. As I enter the kitchen to make a pot of tea, I see the Scripting Wife at her computer. She seems to be experiencing a bit of frustration. I decide to see if I can make my pot of tea and sneak out of the room without being caught.

“Well there you are,” she says.

“Uh, oh. Too late. I am done for,” I think to myself.

I give her my “Who me, I’m innocent” look, whilst attempting to ease my way towards the door.

“I see you trying to sneak off,” she said.

“Uh, well good morning Scripting Wife,” I said in my most subdued cheerful voice. “How are you doing this fine morning?”

“So what are you up to?” she asked.

“I was just sitting here contemplating my Live Meeting that starts in a couple of hours,” I said.

“Well contemplate this: I would like to query all of the files in the myfriends directory, and pull out a two column list of friend’s names and phone numbers,” she said.

“Oh, I see.”

“What about it, can you help me?”

“Yes, I can help you. I am still deciding if I want to help you right now.”

“When will you decide? I have got things to do today, and they do not include sitting around here all day watching you sit there and contemplate your naval,” she said.

“I’m contemplating the Live Meeting for today, not my navel. Besides, I have my shirt on, I cannot even see my navel.”

“That is why you must contemplate it,” she said with wisdom.

“Oh. I see. Why don’t you contemplate starting up the Windows PowerShell ISE so you can write a script to create your phone list,” I said. “The first thing you need to do is to create an empty hashtable.”

“A hash what,” she said with a bit of obvious concern.

“A hashtable. You can use a hashtable to store pieces of information. It is sort of like an Excel spreadsheet with only two columns in it. In the first column, you can store your friend’s name, and in the second column you can store the phone number.”

“OK,” she said with resignation. “Tell me what to type.”

“Create a variable named dollar hash, and set it equal to at sign, left curly bracket, right curly bracket,” I said.

The Scripting Wife’s eyes brightened a bit with recognition.

“I can do that,” she said while clicking the keyboard. The code shown here is what she typed.

$hash = @{}

“Good, now that was not too bad, was it?” I said encouragingly.

“I am not stupid. I know how to type. What I don’t know is what that means,” she added.

“OK, open the Windows PowerShell console, and type that same code. After you have done that, pipe $hash to the Get-Member cmdlet,” I instructed.

The Scripting Wife typed for a second, and then sat back to examine the results. Her command and the associated output are shown here (gm is an alias for the Get-Member cmdlet).

PS C:\> $hash = @{}

PS C:\> $hash | gm

 

   TypeName: System.Collections.Hashtable

 

Name              MemberType            Definition

----              ----------            ----------

Add               Method                System.Void Add(System.Object key, System...

Clear             Method                System.Void Clear()

Clone             Method                System.Object Clone()

Contains          Method                bool Contains(System.Object key)

ContainsKey       Method                bool ContainsKey(System.Object key)

ContainsValue     Method                bool ContainsValue(System.Object value)

CopyTo            Method                System.Void CopyTo(array array, int array...

Equals            Method                bool Equals(System.Object obj)

GetEnumerator     Method                System.Collections.IDictionaryEnumerator ...

GetHashCode       Method                int GetHashCode()

GetObjectData     Method                System.Void GetObjectData(System.Runtime....

GetType           Method                type GetType()

OnDeserialization Method                System.Void OnDeserialization(System.Obje...

Remove            Method                System.Void Remove(System.Object key)

ToString          Method                string ToString()

Item              ParameterizedProperty System.Object Item(System.Object key) {ge...

Count             Property              System.Int32 Count {get;}

IsFixedSize       Property              System.Boolean IsFixedSize {get;}

IsReadOnly        Property              System.Boolean IsReadOnly {get;}

IsSynchronized    Property              System.Boolean IsSynchronized {get;}

Keys              Property              System.Collections.ICollection Keys {get;}

SyncRoot          Property              System.Object SyncRoot {get;}

Values            Property              System.Collections.ICollection Values {get;}

“You will notice that there is an add method for the HashTable class.”

“Yes, but it is cut off and I cannot see what it says,” she complained.

“Use your Up arrow to retrieve your previous command. This time type the word add after your Get-Member command.”

The Scripting Wife did not hesitate for even the blink of an eye. In less than a second, she had typed the following command (remember gm is an alias for the Get-Member cmdlet. When you are working interactively in the Windows PowerShell console, the use of aliases can simplify typing).

$hash | gm add

The command and its associated output are shown here.

PS C:\> $hash | gm add

 

   TypeName: System.Collections.Hashtable

 

Name MemberType Definition

---- ---------- ----------

Add  Method     System.Void Add(System.Object key, System.Object value)

“As you can see, my dear Scripting Wife, the Add method accepts two parameters. The first parameter is the key and the second is the value. All this means is that the key must be unique among all of the items you store in the hashtable. Therefore, if you use the friend’s names as the key property, you cannot have two friends with the same name. If you did have two friends with the same name, you would need to add something like a number to the end of their name to make them unique. Another approach would be to use the telephone number as the key, but then if you had several people from the same family, it is possible that they would have the same phone number.”

“OK. I get it already. What do I need to do now?” she asked.

“Well you need to add a switch statement. One easy way to do this would be to use the code snippet that I created, but I do not think you have it installed on your computer,” I said.

“No, I did not add that to my profile…in fact, I am not certain I have a profile,” she said.

I leaned over and looked at her from the side, “You have a very nice profile.”

“Smart alec. How do I add a switch statement?” she asked.

“You need to type the word switch and use the regex switched parameter. Then you use the Get-Content command that you used yesterday to read the content from all your files. Next, you open and close a set of curly brackets.”

The Scripting Wife thought for a second and typed the following command.

Switch -regex (Get-Content -Path C:\MyFriends\*)

{

}

I looked over at her computer, and gave her a reassuring nod before proceeding. “Now you need to add two conditions. The first condition is the regular expression pattern you created earlier that finds your friend’s names. The second condition is the regular expression pattern that finds their phone numbers. Follow those patterns with an open and closed set of curly brackets.”

She thought for a minute, then found the file where she had stored the commands. She cut and pasted them into the Windows PowerShell ISE. Here is what she typed.

'^[a-zA-Z]+\s+[a-zA-Z]+$' { }

 '^\d{3}-\d{3}-\d{4}$'     { }

So far, this is what she has typed.

$hash = @{}

Switch -regex (Get-Content -Path C:\MyFriends\*)

{

 '^[a-zA-Z]+\s+[a-zA-Z]+$' { }

 '^\d{3}-\d{3}-\d{4}$'     { }

}

“OK. That is looking good. Now you need to add your action that goes inside the curly brackets for each of your regex conditions. The first one will be the name. Use the $name variable to store the name from the current $switch variable,” I said.

She thought for a second and then added the command. The line shown here is her revised line.

'^[a-zA-Z]+\s+[a-zA-Z]+$' {$name = $switch.current}

“Now, the next addition you need is a bit more complicated. Therefore, you might wish to begin on a blank line inside your pair of curly brackets.”

“OK. I am ready,” she said.

“First you need to use the same syntax that you used for the name, and assign the current line from the $switch variable to the $phone variable. Next, you use the add method from the hashtable that you created and stored in the $hash variable to add the name and phone to your hashtable. Lastly, you need to assign $null to the $name and $phone variables.”

This time, the Scripting Wife took her time. When she was finished, the revised code looked like the code shown here.

'^\d{3}-\d{3}-\d{4}$'     {

                            $phone = $SWITCH.CURRENT

                            $hash.Add($name,$phone)

                            $name=$phone=$null

                            }

“Very good,” I said. “Now you only need to display the contents of the $hash variable. Put it at the very bottom of your script.”

The Scripting Wife added the $hash variable to the very end of her script. The complete script that she created is shown here.

SearchTextReturnNameAndPhoneNumber.ps1

$hash = @{}

Switch -regex (Get-Content -Path C:\MyFriends\*)

{

 '^[a-zA-Z]+\s+[a-zA-Z]+$' {$name = $switch.current}

 '^\d{3}-\d{3}-\d{4}$'     {

                            $phone = $SWITCH.CURRENT

                            $hash.Add($name,$phone)

                            $name=$phone=$null

                            }   

}

$hash

The script and its associated content are shown in the following image.

Image of command output

“I don’t know why you were whining this morning. It did not take very long at all,” she said.

“Well, I had some good help,” I said.

“Yeah, right. I have got to go. Good luck in your Live Meeting,” she said.

“I thought you were going to sign in and listen,” I said.

“Well, maybe. But Amy and I already had plans. We are going out to breakfast, and then heading to the mall. We want to be there when it opens,” she said.

“But the mall takes less than 30 minutes to get to,” I pleaded.

“Not our mall. We are going to the mall in Columbia, South Carolina. It will take us a couple of hours to drive there, so we need an early start.”

“Oh. I see. Have fun.”

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • <p>&quot;The registration for the 2011 Scripting Games is going well,&quot;. Where can I register? I&#39;ve been to the script center and the &quot;2011 Scripting Games: All Links on One Page&quot; and I still can&#39;t find out where to sign up.</p>

  • <p>You can register at PoshCode <a rel="nofollow" target="_new" href="https://auth.poshcode.org/hrd">https://auth.poshcode.org/hrd</a> sign in and create your account. </p>

  • <p>&quot;Naval&quot; means &quot;referring to a navy&quot;. &nbsp;The formal name for a belly button is &quot;navel&quot;.</p>

  • <p>@Monty</p> <p>You are absolutely correct ... I cannot believe I missed that! But, of course, I used to be in the Navy, so perhaps I was contemplating my time on a ship ... not sure why I would be doing that ... Certainly not sure why the Scripting Wife would accuse of me of such a thing. So I will confess, it was a silly mistake. Good catch. I have corrected the post. </p>