Search code examples
powershellnested-loopsstring-matching

PowerShell: Finding if a word in a text file is part of an array of strings


I have a folder with a bunch of .txt files. I want to iterate through them and check if any of them contains a keyword stored in an array of strings. If one match is found I want to store the file in a new folder named after the match. For example, I am checking if the word "OVERTIME" is in one of my text files; if a match is found I want to save the file in a new folder titled "OVERTIME". I intend on using move-item to move the file from the current folder to the new one that way the file gets deleted from the old folder. Below is my initial code; I am not sure how to set up the nested loop and how I can check if there is a match.

$reports_name = @('MYTIME','NOTIME','OVERTIME')
Get-ChildItem "C:\Users\My_User\Desktop\test" -Filter *.txt | 
Foreach-Object {
$content = Get-Content $_.FullName
foreach($line in $content) {
if($line -in $reports_name){
    move-item $content -Destination C:\Users\My_User\Desktop\$line
}
}

Solution

  • $reports_name = 'MYTIME', 'NOTIME', 'OVERTIME'
    
    Select-String -List $reports_name 'C:\Users\My_User\Desktop\test\*.txt' |
      Move-Item -LiteralPath { $_.Path } `
                -Destination { "C:\Users\My_User\Desktop\$($_.Pattern)" } -WhatIf
    

    Note: The -WhatIf common parameter in the command above previews the operation. Remove -WhatIf once you're sure the operation will do what you want.

    • Select-String with the -List switch only looks for the first match in each input file.

      • Note: Select-String interprets its (implied) -Pattern argument(s) as regular expressions by default; add the -SimpleMatch switch to treat them as literals instead; either way, matching is case-insensitive by default; add -CaseSensitive for case-sensitive matching.
    • The Move-Item call uses delay-bind script blocks to access the properties of the Microsoft.PowerShell.Commands.MatchInfo instances that Select-String outputs on a per-input-file basis (one per input file, thanks to -List).