I have a script that runs on a folder and searches for files based on a cultivated list of keywords. The file names are never the same, but they always contain the same keywords. The files need to be moved to a given location, that list is also cultivated (given).
For instance, a file named “the.tps.report_383-202-5321.csv” would always contain “TPS” and “report” but might sometimes be separated by a hyphen, space, or whatever. I have the table containing strings with wildcards, such as “tpsreport*”. The target folders also have wildcards, but my issue concerns the keywords.
So I made a custom table with properties “keyword” and “Target Folder” and I have my data in there without issue. I am basically filtering down to select only the files I want to move, they are stored in subfolders (one level). My logic here would be: computer, find files with this keyword, and move those into the target folder that matches with it.
$SourcePaths = Resolve-Path -Path "$Complete\*" |
where {$_.Path -notmatch '(\\_)'} # define folder(s), ignore ones starting with underscore
$Keywords = ($Table.Keyword)
$SourceFiles = Get-ChildItem -literalpath $SourcePaths |
Where {$_.Extension -in $FileTypes} |
Where {$_.Name -notlike "*sample*"} |
where {$_.Name -like $Keywords} # This is the PROBLEM I have #
# ...then I would move those $SourceFiles.
The filetypes filter works because there are no wildcards in that array.
The name/keyword filter doesn’t return any data, I assume because it’s not evaluating the wildcards.
How do I check a value against a collection of things with wildcards?
Oh yeah, the filenames often contain [square brackets], which is why I use literalpath.
I won’t be back to reply on any comments until tmrw (FYI). Thanks!
use Regular Expression and the -match operator
$keywords = “.*tps.report.|.*somethingelse.report.”
Get-ChildItem | Where-Object {$_.Name -match $keywords}
This right here shows I need to keep practicing my regex skills. TIL the dot is the real wildcard. Thanks for the reply.
The matching works now, but it doesn’t solve that whole array problem I have. Your long string of OR operators does the trick, but in the end I am moving files into folders based on those keywords, so I am using a table with values, and that’s where I get stuck.
Basically I need to know if this is possible or not, and what my options are. If I have a couple of arrays:
$a = @(
'.*red.*',
'.*blue.*',
'.*green.*yellow.*'
)
$s = @(
'orangeredyellow',
'orangegreenblack',
'orangegreenredblackyellow',
'orangeblueblack',
'brownblackblack'
)
Should I be able to filter out the 2nd and last entry of $s by matching it with $a?
PS D:\ps> $a
.*red.*
.*blue.*
.*green.*yellow.*
PS D:\ps> $s
orangeredyellow
orangegreenblack
orangegreenredblackyellow
orangeblueblack
brownblackblue
PS D:\ps> $s -match $a
PS D:\ps>
I cannot. Even if I use a trusty foreach loop.
PS D:\ps> $S | foreach { $_ -match $a }
False
False
False
False
False
PS D:\ps>
Hi Tony,
Try to remove . (dot) from $a array and use:
$a = @(
'*red*',
'*blue*',
'*green*yellow*'
)
#loop
foreach ($x in $s) { foreach ($y in $a) { $x -like $y} }
Result should look like this:
PS> foreach ($x in $s) { foreach ($y in $a) { $x -like $y} }
True
False
False
False
False
False
True
False
True
False
True
False
False
False
False
$a = @(
'.*red.*',
'.*blue.*',
'.*green.*yellow.*'
)
$s = @(
'orangeredyellow',
'orangegreenblack',
'orangegreenredblackyellow',
'orangeblueblack',
'brownblackblack'
)
$s -match ($a -join "|")
Results:
orangeredyellow
orangegreenredblackyellow
orangeblueblack
Another example
$a = @(
'.*red.*',
'.*blue.*',
'.*green.*yellow.*'
)
$s = @(
'orangeredyellow',
'orangegreenblack',
'orangegreenredblackyellow',
'orangeblueblack',
'brownblackblack'
)
"-------------------------------------------------------------------------"
$s -match ($a -join "|")
"-------------------------------------------------------------------------"
$s -match $a[0] | ForEach-Object { "$_ move to folder red" }
"-------------------------------------------------------------------------"
$s -match $a[1] | ForEach-Object { "$_ move to folder blue" }
"-------------------------------------------------------------------------"
$s -match $a[2] | ForEach-Object { "$_ move to folder green and yellow" }
"-------------------------------------------------------------------------"
Results:
orangeredyellow
orangegreenredblackyellow
orangeblueblack
orangeredyellow move to folder red
orangegreenredblackyellow move to folder red
orangeblueblack move to folder blue
orangegreenredblackyellow move to folder green and yellow
Thanks Kamil, I had wanted to avoid the nested loop for better readability.
Curtis, thanks again, this will work. It’s one of those ‘why didn’t i think of that’ moments… 