CM_Heroman
CM_Heroman

Reputation: 378

Using select-string to find 2 strings in the same document

I am trying to write a powershell command to search files that contain BOTH strings input by the user. Right now I can search for the one string, but can not figure out how to make sure that it has both strings. Any help would be greatly appreciated.

I am searching in a local directory that stores a bunch of .SQL files. The file path is input by the user (C:\Program Files\Common Files), Then the first string is input by the user, and last the second string. I need the script to search thru all the files and only display the files with both strings in the document.

#Requests the loctation of the files to search
$Location = Read-Host 'What is the folder location of the files you want to search?'

#Sets the location based off of the above variable
Set-Location $Location 

#Sets the alias
Set-Alias ss Select-String 

#Requests the text to search for in the files
$File_Name = Read-Host 'Object Name?'
$File_Name2 = Read-Host 'Second Object Name'

#Searches the files and returns the filenames
Get-ChildItem -r | Where {!$_.PSIsContainer} | ss -Pattern '($File_Name|$File_Name2)'  | Format-List FileName

Upvotes: 3

Views: 4229

Answers (3)

Keith Hill
Keith Hill

Reputation: 201662

A perhaps more simple approach is to just use Select-String twice:

$filename1 = [regex]::escape($File_Name)
$filename2 = [regex]::escape($File_Name2)
Get-ChildItem -r | Where {!$_.PSIsContainer} | Select-String $filename1 | 
    Select-String $filename2

Upvotes: 5

Vasili Syrakis
Vasili Syrakis

Reputation: 9601

Trevor Sullivan's solution looks good to me, but if you wanted a pure regex way of doing this, you would use the following string:

string1(?=string2)|string2(?=string1)

Which basically says,

Try to find string1 and string2 after it somewhere,

otherwise try to look for string2 and string1 after it somewhere.

You'd need to search the whole file raw, not line by line, for this to work.

Upvotes: 2

user189198
user189198

Reputation:

This should work for you. Check out the in-line comments.

# 1. Let's assume the folder c:\test contains a bunch of plain text files
#    and we want to find only the ones containing 'foo' AND 'bar'
$ItemList = Get-ChildItem -Path c:\test -Filter *.txt -Recurse;

# 2. Define the search terms
$Search1 = 'foo';
$Search2 = 'bar';

# 3. For each item returned in step 1, check to see if it matches both strings
foreach ($Item in $ItemList) {
    $Content = $null = Get-Content -Path $Item.FullName -Raw;
    if ($Content -match $Search1 -and $Content -match $Search2) {
        Write-Host -Object ('File ({0}) matched both search terms' -f $Item.FullName);
    }
}

After creating several test files, my output looks like the following:

File (C:\test\test1.txt) matched both search terms

Upvotes: 4

Related Questions