Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Recursive Directory Loop, Match a Filename and Manipulate the File

I'm a Powershell novice so apologies for any wrong terminology. I've had a look on SE and I know how to recursively descend into a directory structure, however all the working examples I can find seem to pipe the output of Get-ChildItem, which I can't understand how to further work with the file before the loop iterates.

What I'm trying to do

  • Provide my script with a directory: C:\Users\Donglecow\myPictures\.
  • Recursively loop through all directories in the defined directory (I have an extensive file structure).
  • Find all files which match a filter thumbnail*.jpg, EG: thumbnail_001.jpg
  • Rename the file to BACKUP-thumbnail*.jpg
  • Check the dimensions of that image in pixels and print them out to the command line

What I've got so far

param (
    [string]$dir = $pwd
)
write-output "Working from $($dir)"

$foundJpg = get-childitem -Recurse -Filter thumbnail*.jpg $dir
foreach($file in $foundJpg) {
    write-output "Found $($file)"
    #Rename to Backup...
    #Check image dimensions...
    #Do other stuff...
}

This works and outputs the correct file name, but when I try to rename the file I get an error.

Rename-Item -NewName { $_.Name.replace("thumbnail", "SAFE-thumbnail.jpg") }

Rename-Item : Cannot evaluate parameter 'NewName' because its argument is specified as a script block and there is no
input. A script block cannot be evaluated without input.
At C:\Users\Donglecow\myPictures\med.ps1:9 char:23
+ ... -Item -NewName { $_.Name.replace("thumbnail", "SAFE-thumbnail.jpg") }
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : MetadataError: (:) [Rename-Item], ParameterBindingException
    + FullyQualifiedErrorId : ScriptBlockArgumentNoInput,Microsoft.PowerShell.Commands.RenameItemCommand

I've deducted this is probably because I've tried to adapt from a command that pipes the output as shown in answers on this question:

Get-ChildItem -Recurse -Filter *.mp3 | Rename-Item –NewName { $_.name –replace 'xyz','abc' }

Whereas I'm using a different construct for my loop so that I can further interact with each file that I find.

My environment

For reference, a snippet of my file structure is below.

C:\Users\Donglecow\myPictures\
1\001\thumbnail_001.jpg
1\002\thumbnail_001.jpg
1\003\thumbnail_001.jpg
2\001\thumbnail_001.jpg
etc...

Where am I going wrong here?

like image 545
Donglecow Avatar asked Dec 07 '25 22:12

Donglecow


1 Answers

Try this:

foreach($file in $foundJpg) {
     $File | Rename-Item -NewName { $_.Name.replace("thumbnail", "SAFE-thumbnail.jpg") }
     #Do other stuff...
}

You need to use $file as the input of the command (which you should be able to do via the pipeline as shown above) as this is what your ForEach loop is using to represent each item retrieved by Get-ChildItem into the $foundJpg variable.

like image 87
Mark Wragg Avatar answered Dec 10 '25 11:12

Mark Wragg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!