Home > Net >  Powershell - Scan for multiple strings in multiple files
Powershell - Scan for multiple strings in multiple files

Time:02-11

I am having issues resolving a revision to the script below. This script will take in a number of key words, either manually added or read from a file. It will output the data when it finds a match by listing the File Name, Line number and the search word. Unfortunately if I'm searching for multiple words it has to scan the files for each separate word. That means if I have 20 search words, it will open, scan, close each file 20 times. Once for each word. Not good as it takes time and I still have to troll through the output to total how many matches per file. Every change I make is disastrous as it prints every single search word without knowing what word was the match or worse it fails to run. Would anyone be able to help me alter the script to scan the files once for ALL the search words and list out only the matches in a readable way like the output below?

Regards, -Ron

$searchWords="Address", "City","State"
Foreach ($sw in $searchWords)
{
    Get-Childitem -Path "C:\Workspace\src" -Recurse -include "*.cbl" | 
    Select-String -Pattern "$sw" | 
    Select Path,LineNumber,@{n='SearchWord';e={$sw}}

}

CodePudding user response:

-Pattern accepts an array of patterns, and which of those pattern caused a given match can be accessed via the .Pattern property of Select-String's output objects:[1]

Get-Childitem -Path "C:\Workspace\src" -Recurse -include "*.cbl" | 
  Select-String -Pattern "Address", "City", "State" | 
    Select Path, LineNumber, @{n='SearchWord';e={$_.Pattern}}

Note: I'm passing the search words as a literal array here, for brevity; in your code, simply replace "Address", "City", "State" with $searchWords (without enclosure in "...").


As an aside: Using -Filter instead of -Include can speed up your command, and, given that your command arguments don't contains spaces or other metacharacters, quoting them is optional:

Get-Childitem -Path C:\Workspace\src -Recurse -Filter *.cbl | 
  Select-String -Pattern Address, City, State | 
    Select Path, LineNumber, @{n='SearchWord';e={$_.Pattern}}

[1] Note: Only the first among the specified pattern that matches, in the order specified, that matches on a given line is reported as the matching pattern for that line - even if others would match too. Even -AllMatches doesn't change that - it would only report multiple matches per line for that first pattern.

  • Related