0

I have a task that I am trying to resolve and I thought I would have a go at using PowerShell.

From this tutorial I found out that I can read a text file and display it like this:

 # C:\Users\Andrew> Get-Content -Path d:\TextToFind.txt

Then, based on another tutorial I tried to do a serach in text files for a phrase:

 $Path = "D:\My Programs\2017\MeetSchedAssist\Meeting Schedule Assistant"
 $Text = "ID_STR_THIS_VERSION"
 $PathArray = @()
 $Results = "D:\Results.txt"

 # But I want to IGNORE "resource.h"
 # But I want to filter for *.h AND *.cpp
 Get-ChildItem $Path -Filter "*.cpp" | Where-Object { $_.Attributes -ne "Directory"}

 ForEach-Object {
    If (Get-Content $_.FullName | Select-String -Pattern $Text) {
        $PathArray += $_.FullName
        $PathArray += $_.FullName
    }
 }
 Write-Host "Contents of ArrayPath:"
 $PathArray | ForEach-Object {$_}

Doesn't work:

Error

Specially, what I am wanting to do is this:

For each line of text in TextToFind.txt
    Examine all CPP and H files in folder XXX - but ignore RESOURCE.H
    If the file DOES NOT use this line of text
       Append the line of text to a log file.
    End If
End For

I know that the script written does not do this. But I am failing at the furst hurdle.

Update

Based on the comments and answer I have tried this:

# Read in the STRINGTABLE ID values I want to locate
$TextToFind = Get-Content -Path d:\TextToFind.txt

$Path = "D:\My Programs\2017\MeetSchedAssist\Meeting Schedule Assistant"
$Text = "ID_STR_THIS_VERSION"
$PathArray = @()
$Results = "D:\Results.txt"

# But I want to IGNORE "resource.h"
# But I want to filter for *.h AND *.cpp

# First you collect the files corresponding to your filters
$files =  Get-ChildItem $Path -Filter "*.cpp" | Where-Object { $_.Attributes -ne "Directory"}

# Now iterate each of these text values
$TextToFind | ForEach-Object {
    $Text = $_
    Write-Host "Checking for: " $Text

    # Then, you enumerate these files and search for your pattern
    $InstancesFound = $FALSE
    $files | ForEach-Object {
        If ((Get-Content $_.FullName) | Select-String -Pattern $Text) {
            $PathArray += $Text + " " + $_.FullName
            $InstancesFound = $TRUE
        }
    }
    if($InstancesFound -eq $FALSE) {
        $PathArray += $Text + " No instance found in the source code!"
    }
}



Write-Host "Contents of ArrayPath:"
$PathArray | ForEach-Object {$_}

The only issue with the above is that it does not factor for ignoring resource.h and I can't seem to filter for .h and .cpp.

3
  • 1
    > ForEach-Object { For what object? You do not pass anything to Foreach-Object CMDlet. Just add the pipe | after Where-Object expression. Commented Feb 16, 2017 at 10:46
  • @n01d Thanks. That gets me up and running. Now I got to work out the rest of what to do. :) Commented Feb 16, 2017 at 10:50
  • 1
    About your issue, -Filter only accepts a single string. -Include accepts multiple values, but qualifies the -Path argument. The trick is to append * to the end of the path, and then use -Include to select multiple extensions. So your statement would become something like: $files = Get-ChildItem -Path $Path* -Include ".cpp", ".h" Commented Feb 16, 2017 at 12:04

2 Answers 2

1

I guess what you want should resemble this:

 $Path = "D:\My Programs\2017\MeetSchedAssist\Meeting Schedule Assistant"
 $Text = "ID_STR_THIS_VERSION"
 $PathArray = @()
 $Results = "D:\Results.txt"

 # But I want to IGNORE "resource.h"
 # But I want to filter for *.h AND *.cpp

 # First you collect the files corresponding to your filters
$files =  Get-ChildItem -Path "$Path\*" -Include "*.cpp", "*.h" | Where-Object { $_.Attributes -ne "Directory"}

 # Then, you enumerate these files and search for your pattern
 $files | ForEach-Object {
    If ((Get-Content $_.FullName) | Select-String -Pattern $Text) {
        $PathArray += $_.FullName
    }
 }
 Write-Host "Contents of ArrayPath:"
 $PathArray | ForEach-Object {$_}
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you. But what if I want to perform this check on each line of this text file: d:\TextToFind.txt
It won't accept the filter you have suggested. I can only use "*.cpp". It won't accept a array of string values.
I have accepted your answer. For the main part it is working. I just can't get it to filter for two types of files without giving me an error.
You can always just add that to the where statement: $files = Get-ChildItem $Path -File | Where-Object {$_.Extension -eq ".cpp" or $_.Extension -eq ".h"} .The -File can filter for only files, but you could also leave that in the where statement: ChildItem $Path | Where-Object {($_.Extension -eq ".cpp" or $_.Extension -eq ".h") -and ($_.Attributes -ne "Directory")} or just leave it out altogether since a folder should never have an extension: $files = Get-ChildItem $Path | Where-Object {$_.Extension -eq ".cpp" or $_.Extension -eq ".h"}
1

The easiest way IMO would be to use Select-String on the path instead of getting the content and figuring out what files have matching lines.

Find all matching entries for the search text:

$files = (Get-ChildItem -Filter @("*.cpp","*.h") -Exclude "Resource.h"
$matches = ($files|Select-String $text)

If you then type $matches, you will see that this is an array of MatchInfo objects. This means you will have contextual reference on where in what file it also matches.

If you're just interested in the filename, you can e.g. group this to just show your unique files where it's a match.

Unique matches (Selecting just filename)

$uniqueFiles = $matches|Select-Object -Unique FileName

From here you would have two arrays, one of all the files your scanning and one with all the matching ones. They'd be easy to substract as a set.

If you want to write the results back to a file (results file), you can easily just pipe it further using | Set-Content.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.