0

I have a lot of files with same name but different extensions in different folders (usually .jpg, .crw and .xmp). Files with appropriate metadata have been moved to their own folders, but especially raw files have stayed in the root folder (or upper folders).

Current situation:

C:\Source\Pictures\
  FileOne.CRW
  FileTwo.CRW
  FileXXX.CRW
C:\Source\Pictures\Metadata\
  FileOne.XMP
  FileOne.JPG
  FileTwo.XMP

What I'm looking for:

C:\Source\Pictures\
  FileXXX.CRW
C:\Source\Pictures\Metadata\
  FileOne.XMP
  FileOne.CRW
  FileOne.JPG
  FileTwo.XMP
  FileTwo.CRW

It would be best if raw files (.CRW, .CR2) are moved to the folder where corresponding .xmp/.jpg/.tif files are located, but it would be also sufficient if all corresponding files are moved to one folder.

I've tried the following, but it only works with two file types. And it moves all files to one destination folder. I am fairly okay with this, but it would be better if it could handle more extensions, and move raw files to the folders where .XMP (or .JPG/.TIF) files are.

## INPUT DETAILS
$source_Path = Read-Host -Prompt 'Enter source path'
$dest_Path = Read-Host -Prompt 'Enter destination path'

$ext_GetName = Read-Host -Prompt 'Enter extension name of RAW file (default: ARW)'
if(-not($ext_GetName)){
    $ext_GetName = 'ARW'
}
elseif($ext_GetName.Length -ge 4){
    Write-output "Extension name is not compatible, make sure you are typing the input max of 3 characters only."
    $ext_GetName = Read-Host -Prompt 'Enter extension name of RAW file (default: ARW)'
}


$ext_FindName = Read-Host -Prompt 'Enter extension name of compressed pictures (default: JPG)'
if(-not($ext_FindName)){
    $ext_FindName = 'JPG'
}
elseif($ext_FindName.Length -ge 4){
    Write-output "Extension name is not compatible, make sure you are typing the input max of 3 characters only."
    $ext_FindName = Read-Host -Prompt 'Enter extension name of compressed pictures (default: JPG)'
}



## IF YOU WANT TO USE STATIC DETAILS
## -------------------#

## EXTENSION NAMES
#$ext_GetName = "CR2"
#$ext_FindName = "JPG"
## PATH
#$source_Path = "F:\Pictures\FAMILY, LOVE, FRIENDS, TRAVEL PHOTOS\_Photo Archives\2022-11-28 (AYALA LIGHTS)"
#$dest_Path = "c:\temp\test"
## -------------------#

$ext_GetName_incl = "*."+$ext_GetName
$ext_FindName_incl = "*."+$ext_FindName

$RAWfiles = Get-ChildItem -Path $source_Path -Include $ext_GetName_incl -Recurse -Force -ErrorAction SilentlyContinue

$COMPfiles = Get-ChildItem -Path $source_Path -Include $ext_FindName_incl -Recurse -Force -ErrorAction SilentlyContinue

write-host "Looking for "$ext_GetName" files for chosen "$ext_FindName" files in "$source_Path

##FOR TESTING## Get-ChildItem -Path $source_Path -Include $ext_xxxxx_xxx -Recurse -Force -ErrorAction SilentlyContinue

$counter=0
foreach( $RAWfile in $RAWfiles ) 
{
    foreach( $COMPfile in $COMPfiles ) 
    {   
        if(($RAWfile.BaseName -eq $COMPfile.BaseName)) 
        { 
            write-host Successfully copied $RAWfile.name 
            Move-Item $RAWfile.fullname $dest_Path
            Move-Item $COMPfile.fullname $dest_Path
            $counter++
        }
    }
}

write-host Successfully copied $counter files to $dest_Path
pause

Any help would be appreciated!

3
  • Hello, what did you try? This is not free scripting website. Writing this should be more or less straightforward with any research. You should show some attempt and let us know about problems you encountered with it.
    – Destroy666
    Commented Jan 12 at 11:47
  • Hi, sorry for that, but also thanks for the info! I agree that this should be more or less straight forward, but I guess my research or more likely capabilities weren't enough. I added more information to the question. Commented Jan 12 at 12:26
  • Wildcard? filename.*
    – JW0914
    Commented Jan 12 at 13:13

1 Answer 1

0

Here's an example in powershell:

$src = "C:\Source"
$dst = "C:\Destination"

# get all the files including in subfolders, without including directory names
$files = Get-ChildItem $src -Recurse -File

# group files by name, and only the ones with matches
$grouped = $files | Group-Object -Property BaseName | Where Count -GE 2
foreach ($group in $grouped){

  # copy each group of files to a single folder
  $group.Group.Fullname | Copy-Item -Destination (Join-Path $dst $group.Name)

}

For example, the files in this source folder:

C:\Source\Pictures\RAW\
  FileOne.ARW
  FileTwo.ARW
  FileThree.ARW
C:\Source\Pictures\Compressed\
  FileOne.JPG
  FileTwo.JPG

will get copied to the destination like:

C:\Destination\FileOne\
  FileOne.ARW
  FileOne.JPG
C:\Destination\FileTwo\
  FileTwo.ARW
  FileTwo.JPG
3
  • Thanks for your effort! Maybe I was a bit unclear with my goals, but I'm looking for a solution which would compare file names, and act only on the ones which have a match. Actually the script I posted in the question does that. And it actually does look for sub folders as well. The only thing is that it should move ALL matching files to destination folder (and preferably be able to handle more than just one file extension). I will continue to find a solution since I'm also quite certain it will be an easy one. Commented Jan 15 at 8:46
  • @joukaha1nen I've updated my answer to only act on files which have a match. It does everything else you've written so far though, so try testing it out? If it doesn't work for you, you might have to add more examples of before+after file paths to your question
    – Cpt.Whale
    Commented Jan 16 at 16:27
  • Thanks a lot for the update! I tried it but at least in my test it copied only the .xmp files, without extensions? Or did I miss something... Anyway, I updated my question with examples, and also updated the script I was using. It now moves both raw and compressed files to destination folder, but I would like it to handle more extensions and if possible, move the files to the folder where compressed (or .xmp) files are. Commented Jan 17 at 12:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .