Home > Back-end >  Copy files into newly created folders on partial filename match
Copy files into newly created folders on partial filename match

Time:05-27

Hi all reaching out because I've reached the limits of my powershell knowledge.

I have a directory that has over 200,000 files, I need to copy all files that have a partial match to the filename into folders that I have already created using this script

Set-Location "C:\Users\joshh\Documents\Testing Environment" 
$Folders = Import-Csv "C:\Users\joshh\Documents\Weichert.csv" 
ForEach ($Folder in $Folders) { 
New-Item "myfilepathhere\$($Folder.folderName)" -type directory 
}

UPDATED: Here is a sample of the filenames:

TH-246-02050-LOL-SQ-ALT2.png
TH-246-02050-WHT-H.png
TH-247-02050-EMB-LOD.png
TH-246-02050-LOL-H-ALT2.png
TH-246-02050-LOL-SQ.png
TH-246-02050-LOL-SQ-ALT.png
TH-247-02050-EMB-LOD-ALT.png
TH-247-02050-EMB-LOL.png
TH-247-02050-EMB-LOL-ALT.png
TH-247-02050-LOD-H.png

Above is an example of what the filenames look like, I need to copy all files containing -EMB- and move them into folders in another directory that match the first 12 characters of that filename (ex. TH-247-02050)

UPDATED: And if a folder doesn't exist create a folder with the first 12 characters of the filename. Mind you the first 12 characters have many variants some start with RM, KW, etc.

This is what I have so far and what I know but I know the Move-Item portion isn't exactly what I want it to do

$source = "targetPath"
$destination = "targetPath2"

$embFiles = @(Get-ChildItem ${source}/*EMB* -File | Select-Object -ExpandProperty FullName)
foreach($file in $embFiles) {
    if($file | Where-Object { $_ -clike "*EMB*" }){
    Move-Item -Path $source -Destination $destination
        }
}

Any and all help would be GREATLY appreciated!

CodePudding user response:

Here is one way you could do it:

  1. Get all files that contain -EMB- in their names: -Filter *-EMB-* -File.
  2. Group all this files by everything before -EMB-, here we can use Group-Object -AsHashTable and a calculated expression using Regex.Match. See https://regex101.com/r/iOoBJS/1 for details.
  3. Loop through the Keys of the hash table, each Key will be the Name Destination folder of the group of files (i.e.: TH-247-02050).
  4. Join the destination path ($destinationPath2) with the name of the destination folder ($folder), here we can use Join-Path and check if this joined path exists, if it doesn't, create a new folder with New-Item.
  5. Lastly, we can move all the files (the Values of each Key from the hash table) to their corresponding destination.
$source      = "targetPath"
$destination = "targetPath2"

$map = Get-ChildItem $source -Filter *-EMB-* -File | Group-Object -AsHashTable -AsString {
    [regex]::Match($_.BaseName, '(?i). (?=-EMB-)').Value
}

foreach($folder in $map.Keys) {
    $d = Join-Path $destination -ChildPath $folder
    if(-not (Test-Path $d -PathType Container)) {
        $d = New-Item $d -ItemType Directory
    }
    # -WhatIf can be removed once you have checked the script is doing what you want
    $map[$folder] | Move-Item -Destination $d -WhatIf -Verbose
}

-AsString is needed in Windows PowerShell due to a bug.

  • Related