I have a folder including sub-folders in my Windows PC where I have multiple files of images with different dimensions with standard formatted names as shown below.
- first-image-name.jpg
- first-image-name-72x72.jpg
- first-image-name-150x150.jpg
- first-image-name-250x250.jpg
- first-image-name-300x300.jpg
- first-image-name-400x400.jpg
- first-image-name-1024x1024.jpg
- second-image-name.png
- second-image-name-72x72.png
- second-image-name-150x150.png
- second-image-name-250x250.png
- second-image-name-300x300.png
- second-image-name-400x400.png
- second-image-name-1024x1024.png
Now I want to delete all those image files that are of different sizes as shown in their name and should leave the original one only.
For that, I tried many queries as shared below but non of these are working...
Windows PowerShell:
Get-ChildItem $Path | Where{$_.Name -Match '.*[0-9] x[0-9] .\(jpg\|png\|jpeg\)$'} | Remove-Item
Windows CMD:
find -type f -regex '.*[0-9] x[0-9] .\(jpg\|png\|jpeg\)$' -delete
find -name '.*[0-9] x[0-9] .\(jpg\|png\|jpeg\)$' -delete
None of the above is working so let me know what I am doing wrong...??? Please remember I have to use it as recursive as I have many folders inside the main folder too.
CodePudding user response:
The fourth bird has provided the crucial pointer in a comment:
You mistakenly
\
-escaped the following regex metacharacters in your regex, which causes them to be matched as literals:(
,)
, and|
. Simply omitting the\
would work.Conversely, you neglected to escape
.
as\.
, given that you want it to be interpreted literally.
However, I suggest the following optimization, which pre-filters the files of interest and then matches only against each pre-filtered file's base name (.BaseName
), i.e. the name without its extension:
Get-ChildItem -Recurse $Path -Include *.jpg, *.jpeg, *.png |
Where-Object { $_.BaseName -match '-[0-9] x[0-9] $' } |
Remove-Item -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.
Note:
The regex above needs no
.*
prefix, given that PowerShell's-match
operator looks for substrings by default.- Using character class
\d
in lieu of[0-9]
is an option, although\d
technically also matches digits other than the ASCII-range characters0
through9
, namely anything that the Unicode standard classifies as a digit.
- Using character class
While use of
-Include
, which (unlike-Filter
) conveniently allows you to specify multiple PowerShell wildcard patterns, works as expected in combination with-Recurse
, in the absence of-Recurse
its behavior is counterintuitive:- See this answer for details.