It's always worth using the -Filter
parameter, if available: it performs filtering at the source and is therefore typically much faster than filtering later.
The syntax of the (string) value accepted by the -Filter
parameter is cmdlet- / PowerShell drive provider-specific.
In the case of Get-ChildItem
(and its built-in aliases dir
and, in Windows PowerShell, ls
), it accepts a single wildcard expression - similar to, but distinct from PowerShell's own wildcard expressions - whose supported syntax is platform-dependent:
On Windows, the expression may only contain *
and ?
wildcards - see this answer.
In PowerShell Core on Unix platforms, the expression may also contain character sets such as [0-9]
.
[0-9]+.jpg
does not work as a -Filter
value, because it is a regex (regular expression).
As an aside: You probably meant to use .
as a literal, in which case you'd have to escape it in the regex as \.
, because .
is a regex metacharacter representing any char. in the input.
You cannot emulate regular expression [0-9]+.jpg
with a wildcard expression, because even when wildcard expressions do support character sets such as [0-9]
, they lack subexpression duplication symbols (quantifiers) such as +
and *
and ?
.
(By contrast, wildcard metacharacters *
/ ?
are stand-alone constructs that represent any possibly empty sequence of characters / exactly one character).
Note: -WhatIf
has been added to the Rename-Item
calls below to preview any changes that would be made.
Remove -WhatIf
to perform actual renaming.
[PowerShell Core on Unix only] If all *.jpg
files of interest have a base name (filename root) that is limited to a single-digit number, (e.g., 1.jpg
, ..., 9.jpg
), you can get away with passing wildcard expression [0-9].jpg
to -Filter
:
Get-ChildItem -File -Recurse -Filter [0-9].jpg |
Rename-Item -NewName { $_.BaseName + 'a' + $_.Extension } -WhatIf
Note how passing script-block argument { $_.BaseName + 'a' + $_.Extension }
to parameter -NewName
constructs the new filename from the input file's base name, followed by literal a
, followed by the input file's extension.
Otherwise,
use wildcard expression *.jpg
for efficient pre-filtering,
then narrow the pre-filtered results down to specific regex-based matches with a Where-Object
call that uses -match
to compare each input file's base name to regex ^[0-9]+$
, i.e., to test if it is only composed of decimal digits.
Note:
* The command below uses PSv3+ Get-ChildItem
and Where-Object
syntax.
* The regex passed to -match
uses single-quoting ('...'
) rather than double-quoting ("..."
) to ensure that PowerShell's string interpolation doesn't get in the way.
Get-ChildItem -File -Recurse -Filter *.jpg |
Where-Object BaseName -match '^[0-9]+$' |
Rename-Item -NewName { $_.BaseName + 'a' + $_.Extension } -WhatIf