Jump to content

How to Search a File for Text or a Pattern in Windows PowerShell

0
  chco's Photo
Posted Aug 30 2010 08:08 AM

When you want to find a string or regular expression in a file then the following excerpt from Windows PowerShell Cookbook, Second Edition should be able to help you.
To search a file for an exact (but case-insensitive) match, use the -Simple parameter of the Select-String cmdlet:

PS > Select-String -Simple SearchText file.txt


To search a file for a regular expression, provide that pattern to the Select-String cmdlet:

PS > Select-String "\(...\) ...-...." phone.txt


To recursively search all *.txt files for a regular expression, pipe the results of Get-ChildItem to the Select-String cmdlet:

PS > Get-ChildItem -Filter *.txt -Recurse | Select-String pattern


The Select-String cmdlet is the easiest way to search files for a pattern or specific string. In contrast to the traditional text-matching utilities (such as grep) that support the same type of functionality, the matches returned by the Select-String cmdlet include detailed information about the match itself.

PS > $matches = Select-String "output file" transcript.txt
PS > $matches | Select LineNumber,Line

                        LineNumber Line
                        ---------- ----
                                 7 Transcript started, output file...


With a regular expression match, you’ll often want to find out exactly what text was matched by the regular expression. PowerShell captures this in the Matches property of the result. For each match, the Value property represents the text matched by your pattern.

PS > Select-String "\(...\) ...-...." phone.txt | Select -Expand Matches

...
Value    : (425) 555-1212

...
Value    : (416) 556-1213


If your regular expression defines groups (portions of the pattern enclosed in parentheses), you can access the text matched by those groups through the Groups property. The first group (Group[0]) represents all of the text matched by your pattern. Additional groups (1 and on) represent the groups you defined. In this case, we add additional parentheses around the area code to capture it.

PS > Select-String "\((...)\) ...-...." phone.txt |
    Select -Expand Matches | Foreach { $_.Groups[1] }



Success  : True
Captures : {425}
Index    : 1
Length   : 3
Value    : 425

Success  : True
Captures : {416}
Index    : 1
Length   : 3
Value    : 416


If your regular expression defines a named capture (with the text ?<Name> at the beginning of a group), the Groups collection lets you access those by name. In this example, we capture the area code using AreaCode as the capture name.

PS > Select-String "\((?<AreaCode>...)\) ...-...." phone.txt |
     Select -Expand Matches | Foreach { $_.Groups["AreaCode"] }



Success  : True
Captures : {425}
Index    : 1
Length   : 3
Value    : 425

Success  : True
Captures : {416}
Index    : 1
Length   : 3
Value    : 416


By default, the Select-String cmdlet captures only the first match per line of input. If the input can have multiple matches per line, use the -AllMatches parameter.

PS > Get-Content phone.txt
(425) 555-1212
(416) 556-1213 (416) 557-1214

PS > Select-String "\((...)\) ...-...." phone.txt |
    Select -Expand Matches | Select -Expand Value

(425) 555-1212
(416) 556-1213

PS > Select-String "\((...)\) ...-...." phone.txt -AllMatches |
    Select -Expand Matches | Select -Expand Value

(425) 555-1212
(416) 556-1213
(416) 557-1214


Note: If the information you need is on a different line than the line that has the match, use the -Context parameter to have that line included in Select-String’s output. PowerShell places the result in the Context.PreContext and Context.PostContext properties of Select-String’s output.

If you want to search multiple files of a specific extension, the Select-String cmdlet lets you use wildcards (such as *.txt) on the filename. For more complicated lists of files (which includes searching all files in the directory), it is usually better to use the Get-ChildItem cmdlet to generate the list of files as shown previously in the solution.

Since the Select-String cmdlet outputs the filename, line number, and matching line for every match it finds, this output may sometimes include too much detail. A perfect example is when you are searching for a binary file that contains a specific string. A binary file (such as a DLL or EXE) rarely makes sense when displayed as text, so your screen quickly fills with apparent garbage.

The solution to this problem comes from Select-String’s -Quiet switch. It simply returns true or false, depending on whether the file contains the string. So, to find the DLL or EXE in the current directory that contains the text “Debug”:

Get-ChildItem | Where { $_ | Select-String "Debug" -Quiet }


Two other common tools used to search files for text are the -match operator and the switch statement with the -file option. For more information about the Select-String cmdlet, type Get-Help Select-String.

Cover of Windows PowerShell Cookbook
Learn more about this topic from Windows PowerShell Cookbook, 2nd Edition. 

This introduction to the Windows PowerShell language and scripting environment provides more than 430 task-oriented recipes to help you solve the most complex and pressing problems, and includes more than 100 tried-and-tested scripts that intermediate to advanced system administrators can copy and use immediately. You'll find hands-on tutorials on fundamentals, common tasks, and administrative jobs that you can apply whether you're on a client or server version of Windows.

Learn More Read Now on Safari


0 Replies