How can i compare multiple wildcard patterns on a if statement?
if ($file.Name -like "*test*", "*.tmp")
{
# do something
}
How can i compare multiple wildcard patterns on a if statement?
if ($file.Name -like "*test*", "*.tmp")
{
# do something
}
Unfortunately, neither -like
, the wildcard matching operator, nor -match
, the regular-expression matching operator, support an array of patterns to match against, as of PowerShell 7.2.x:
Having this ability (with any one of the patterns matching being considered an overall match) would be useful; GitHub issue #2132 asks for it to be implemented in a future PowerShell (Core) version.
While PowerShell currently reports no error when you try to use an array on the RHS, its current behavior is virtually useless: the array is stringified to form a single string, which means that its elements are joined with spaces; that is, $file.Name -like "*test*", "*.tmp"
is the same as $file.Name -like "*test* *.tmp"
However, as a workaround you can use -match
with a single regex pattern that uses alternation (|
) to match one of multiple values:
if ($file.Name -match 'test|\.tmp$') {
# do something
}
Note:
-match
matches substrings by default, so there's no need for regex equivalents to the *
wildcard metacharacter.
$
above to assert that subexpression \.tmp
matches at the end of the string.regexes, which are much more powerful than wildcards, have many more metacharacters that may require escaping with \
; in this case, metacharacter .
, which matches any character, must be escaped as \.
in order to be matched as a literal .
[regex]::Escape()
, e.g. [regex]::Escape('.tmp')
, which yields '\.tmp'
.If you prefer to stick with -like
, you need two operations, which you must join with -or
, as js2010 shows in a comment on the question:
if ($file.Name -like '*test*' -or $file.name -like '*.tmp') {
# do something
}
If the number of patterns is large or not known in advance, use a loop, such as via the [intrinsic .ForEach()
method](intrinsic .Where()
method)):
$patterns = '*test*', '*.tmp' # Array of patterns
if ($patterns.Where({ $file.Name -like $_ }, 'First')) {
# do something
}
Finally, it's worth noting that Get-Item
and Get-ChildItem
support -Include
(and -Exclude
) parameters that do support multiple patterns (unlike -Filter
), so you may be able to pre-filter your files, without needing to examine their names later; e.g.:
Get-Item .\* -Include *test*, *.tmp
Unfortunately, -Include
and -Exclude
are notoriously finicky, except (mostly) when -Recurse
is also used; e.g., using Get-ChildItem . -Include *test*, *.tmp
would not work as intended - see this answer for details.