irenetate
irenetate

Reputation: 5

Stop powershell script counting after it gets to three

I have a script that counts how many times a certain word occurs within a file. With the file it keeps adding words and each time the powershell is suppose to count the occurance. However I want to it stop counting once its identified a specific word has been added three times eg:

apple apple apple banana banana apple

I want it to stop counting once its identified apple 3 times and not count it as 4. this is the powershell script that i'm using :

    $ht=@{}
$Output=switch(gc c:\temp\LimitCount.txt){ {($ht.values|sort -Descending|select -first 1) -eq 3}{break}
 {$_ -match '^. +user:(.+)$' -and [string]::IsNullOrEmpty($ht.(([regex]"^(?:. +user:)(.+)$").matches($_).groups[1].value))}{$ht.(([regex]"^(?:. +user:)(.+)$").matches($_).groups   [1].value)=0}
 {$_ -match '^. +user:(.+)$' -and $ht.(([regex]"^(?:. +user:)(.+)$").matches($_).groups[1].value) -eq 3}{continue}
{$_ -match '^. +user:(.+)$'}{$ht.(([regex]"^(?:. +user:)(.+)$").matches($_).groups[1].value)++;([regex]"^(?:. +user:)(.+)$").matches($_).groups[1].value;continue}
 default {$_}
}
"Unfiltered results and count:"
$output|group -NoElement
$output|Where{$ht.keys -contains $_}|group -NoElement

Upvotes: 0

Views: 389

Answers (1)

TheMadTechnician
TheMadTechnician

Reputation: 36322

So you didn't respond to my comment, but we'll assume you want no more than 3 of any single match. What I will do is make an empty hashtable, and run a Switch command on the contents of the file and capture the results in an array

The first validation will check if the string matches the regex, and if that matched text is already in the hashtable. If it does match, and is not in the hashtable it adds it to the hashtable.

The second validation checks if the string matches the regex, and if the hashtable entry is equal to 3. If it is then it skips to the next line of the text file.

The third validation simply checks if the string matches the regex, and if it does it increments the hashtable entry for that match by one, and passes the matched text.

The fourth validation is the default, and if no other validation occurs then it simply passes the line along un-altered.

Then you can output that array, or filter it for only things that matched your regex. The code would look something like this:

$ht=@{}
$Output=switch(gc c:\temp\test.txt){
    {$_ -match '^. +user:(.+)$' -and [string]::IsNullOrEmpty($ht.(([regex]"^(?:. +user:)(.+)$").matches($_).groups[1].value))}{$ht.(([regex]"^(?:. +user:)(.+)$").matches($_).groups[1].value)=0}
    {$_ -match '^. +user:(.+)$' -and $ht.(([regex]"^(?:. +user:)(.+)$").matches($_).groups[1].value) -eq 3}{continue}
    {$_ -match '^. +user:(.+)$'}{$ht.(([regex]"^(?:. +user:)(.+)$").matches($_).groups[1].value)++;([regex]"^(?:. +user:)(.+)$").matches($_).groups[1].value;continue}
    default {$_}
}
"Unfiltered results and count:"
$output|group -NoElement
"Filtered for only matched items:"
$output|Where{$ht.keys -contains $_}|group -NoElement

Given an input of:

A user:Apple
A user:Apple
A user:Banana
Shiney tacos!
A user:Orange
A user:Banana
A user:Apple
A user:Orange
A user:Orange
A user:Apple
A user:Apple
A user:Apple
A user:Apple
A user:Apple

You get an output of:

Unfiltered results and count:
Count Name                     
----- ----                     
    3 Apple                    
    2 Banana                   
    1 Shiney tacos!            
    3 Orange                   
Filtered for only matched items:
    3 Apple                    
    2 Banana                   
    3 Orange

If you want to stop once you reach 3 of any match you can add the following line immediately before the first validation:

    {($ht.values|sort -Descending|select -first 1) -eq 3}{break}

Upvotes: 2

Related Questions