Reputation: 19087
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:
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.
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.
Upvotes: 0
Views: 4349
Reputation: 4743
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
.
Upvotes: 1
Reputation: 43459
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 {$_}
Upvotes: 1