$matches.groups.value of specified length

Hello all. This is my first post on this forum. I have been teaching myself PowerShell by reading online and posting questions at MSDN forums. I stumbled across the forum on Powershell.org today and was hoping someone could help me. I have some code below that is working for me so far, but I need two modifications and do not know how to accomplish either. I want to 1) include the filename of each file in my directory that returns matches and 2) I only want matches that are less than or equal to 100 characters. Thanks :slight_smile: Here is my code:

$searchDir = "C:\\Users\me\"
$outputDir = "C:\\Users\me\results.txt" 
$files = Get-ChildItem $searchDir | Where-Object { $_.FullName -like "*.txt"}
Foreach ($file in $files) {
$FilteredContent = Get-Content $file.FullName
$regex = [regex]'CLP.+?NON-PARTICIPATING'
$matches = $regex.Matches($FilteredContent)
$Output = $matches.groups.value 
$Output | Out-File $outputDir -Append
}

There might be a better / more efficient / faster way of doing what you do. :wink: You may read the (complete) help including the examples for the cmdlet Select-String to level you up.

To make your existing code a little more efficient or faster you should rather use the parameter -Filter for the cmdlet Get-ChildItem instead of using Where-Object to limit the result of Get-ChildItem.

As Olaf said, for 1) you can eliminate the pipe to Where-Object:

$files = Get-ChildItem -Path $searchDir\*.txt

The -Path parameter accepts wildcards like *.

To accomplish 2), you can apply a little logic:

## filepaths
$searchDir = 'C:\\Users\me'
$outputDir = 'C:\\Users\me\tmp'
$outputFile= 'results.txt'

## get txt files
$files = Get-ChildItem -Path $searchDir\*.txt

## filter the files
foreach ($file in $files) {
    
    ## get file contents
    $content = Get-Content $file.FullName

    ## test contents
    if ( $content -match 'CLP.+?NON-PARTICIPATING' -and $content -match '^.{0,100}$' ) {
        $file.FullName, "$content" -join ' : ' | Out-File "$outputDir\$outputFile" -Append
    } ## end if

} ## end foreach

I recommend creating a separate directory to send the results to, otherwise the results file will be captured by the Get-ChildItem statement when the script is run again.

The if statement verifies that the content contains your string and is 100 characters or less. Because the regex strings are only used once, it’s not really useful to store them in variables. The second regex string (^.{0,100}$) is the part that checks the character count. Note that this expects that the characters are all on one line. Alternatively, you could also apply Measure-Object to check the character count.

The output file will look like

filename : contents

If you don’t want them separate by a colon, you can change the characters after -join on line 14.

I used a foreach loop within a foreach loop to check length of all match values not just the first value.

# Get text files
$searchDir = "C:\\Users\me\"
$outputDir = "C:\\Users\me\results.txt"
$file = Get-ChildItem -Path $searchDir -Filter *.txt

$result =
foreach ($f in $file){
 $content = Get-Content $f.FullName
 $match = [regex]::Matches($content,'CLP.+?NON-PARTICIPATING').groups.value

 # If match length is less or equal to 100, create object
 foreach ($m in $match){
   If ($m.Length -le 100){
    [PSCustomObject]@{Name=$f.name;Match=$m}
   }
 }
}

# Export results to your text file or csv
$result | Out-File -FilePath $outputDir
# $dest = join-path -Path (split-path $outputDir) -ChildPath result.csv
# $result | Export-Csv -NoTypeInformation -Path $dest

Hmmm … if I got you right that’s all you need:

$searchDir = 'C:\Users\me\'
$ResultFile = 'C:\Users\me\results.csv'

$FileList = Get-ChildItem -Path $searchDir -Filter *.txt

Select-String -Path $FileList -Pattern '(?<=CLP).{1,100}(?=NON-PARTICIPATING)' |
    Select-Object -Property FileName , @{Name = 'Match'; Expression = {$_.Matches.Value}} |
        Export-Csv -Path $ResultFile -NoTypeInformation 

Thank you all so much for your help with my question. I found random commandline’s solution closest to the result I am looking for. I still have SO much to learn. Any recommendations for good resources for a beginner? Thanks!!

I know - it’s Version 3.0 but the basics are still the same … and this way it’s even entertaining … and it’s Jeffrey Snover explaining all that stuff - how cool is that? :open_mouth: :wink: :smiley:

https://channel9.msdn.com/Series/GetStartedPowerShell3

Thanks Olaf :slight_smile: