August 5th, 2011

Use PowerShell to Open Files That Contain Matching Words

Doctor Scripto
Scripter

Summary: Learn how to use Windows PowerShell to search a folder for matching strings and to open them automatically in Notepad.

 

Hey, Scripting Guy! QuestionHey, Scripting Guy! I have been enjoying using the Select-String cmdlet, but I have a question. When I use Select-String, it lists the file that it finds the match in, but I have to copy and paste from there in order to open it in Notepad. I know that opening a file in Notepad is not very “PowerShell-like” but I still need the ability to quickly find and modify things in Notepad. Can you help me automate this process a bit?

—BL

 

Hey, Scripting Guy! AnswerHello BL,

Microsoft Scripting Guy Ed Wilson here. One of the things I love about Windows PowerShell is the discoverability aspect of the language. For example, it is seemingly impossible to have a comprehensive document on Windows PowerShell. There is just so much that can be accomplished and are so many different ways of using Windows PowerShell that by the time a complete reference guide was produced, several new versions of Windows PowerShell would have been released. Besides, if a complete reference guide were ever written, no one would have time to read it anyway.

To counterbalance this seeming deficit, Windows PowerShell has very good discoverability. One of the primary tools for anyone who wants to get beyond simply running cmdlets with documented switches and parameters is the Get-Member cmdlet.

Note   This is the fifth article in a series of five articles that talk about using the Select-String cmdlet. On Monday, I talked about using the Select-String cmdlet to parse the data returned from an ipconfig command to return only the IP address. On Tuesday, I discussed using the Select-String cmdlet to parse data returned from WMI. Wednesday found me talking about parsing the firewall log, and yesterday I talked about parsing a collection of files in a folder to look for pattern matches in files.

For example, if I pipe the results from a Select-String command, I can see that the command returns a MatchInfo object. This command and output are shown here:

PS C:\fso> dir c:\fso -I *.txt, *.log -R | Select-String fail | gm

 

   TypeName: Microsoft.PowerShell.Commands.MatchInfo

 

Name               MemberType                 Definition

Equals               Method                         bool Equals(System.Object obj)

GetHashCode    Method                         int GetHashCode()

GetType            Method                         type GetType()

RelativePath       Method                         string RelativePath(string directory)

ToString            Method                         string ToString(), string ToString(string directory)

Context             Property                        Microsoft.PowerShell.Commands.MatchInfoContext Conte…

Filename           Property                        System.String Filename {get;}

IgnoreCase        Property                        System.Boolean IgnoreCase {get;set;}

Line                  Property                        System.String Line {get;set;}

LineNumber      Property                        System.Int32 LineNumber {get;set;}

Matches            Property                        System.Text.RegularExpressions.Match[] Matches {get;…

Path                  Property                        System.String Path {get;set;}

Pattern              Property                        System.String Pattern {get;set;}

 

BL, from the preceding output, there are two properties that are of use to help solve your exact scenario. The first property that seems promising is the filename property, and the second property worth investigating is the path property. I will look at both of them by displaying them via the Format-Table cmdlet. Both the command and the associated output are shown here:

PS C:\fso> dir c:\fso -I *.txt, *.log -R | Select-String fail | ft path, filename

 

Path                                          Filename

C:\fso\BackupLog.txt                   BackupLog.txt

C:\fso\BackupLog.txt                   BackupLog.txt

C:\fso\Install.log                         Install.log

C:\fso\Install.log                         Install.log

C:\fso\Install.log                         Install.log

C:\fso\Install.log                         Install.log

C:\fso\Install.log                         Install.log

C:\fso\Install.log                         Install.log

 

BL, it seems I may be on the right track; however, one problem is that from the preceding output, I see multiple matches for each file. If I were to simply choose the path property (and I must choose the path property because it includes both the file and the folder that contains the file) and open the file in Notepad, I would have multiple instances of Notepad displaying multiple copies of the same file.

To work around the problem of multiple matches, I use the list switch from the Select-String cmdlet. The revised command and associated output are shown here:

PS C:\fso> dir c:\fso -I *.txt, *.log -R | Select-String fail -list | ft path, filename

 

Path                                          Filename

C:\fso\BackupLog.txt                   BackupLog.txt

C:\fso\Install.log                         Install.log

 

Cool! Now, all I need to do is to walk through the collection of files that appear and open them in Notepad. I can do this by using the ForEach-Object cmdlet as shown here (the % character is an alias for the ForEach-Object cmdlet and dir is an alias for the Get-ChildItem cmdlet):

dir c:\fso -I *.txt, *.log -R | Select-String fail -list | % { notepad $_.path }

The command and associated output are shown in the following figure.

Image of command and associated output

 

BL, that is all there is to using the Select-String cmdlet to parse text files in a folder, and open the files that contain matches. This also ends Select-String Week. Join me tomorrow as I talk to various community members about starting and running a Windows PowerShell user group. I have two articles this weekend about working with Windows PowerShell user groups—both are important.

I invite you to follow me on Twitter and to join the Scripting Guys group on 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

 

 

Author

The "Scripting Guys" is a historical title passed from scripter to scripter. The current revision has morphed into our good friend Doctor Scripto who has been with us since the very beginning.

0 comments

Discussion are closed.