Search code examples
powershellbatch-filemove

How to move files to folders based on string left to a fixed separator string in each file name?


For example I have a folder called:

FIRSTNAME LASTNAME

And I have the files:

FIRSTNAME LASTNAME CHK#123
FIRSTNAME LASTNAME CHK#145

I want to make a batch to move all files automatically. I have this code from another post:

@echo off
setlocal enabledelayedexpansion
pushd "C:\Folders\"
for %%a in (*) do (
    set fldr=%%~na
    set fldr=!fldr:~0,4!
    md "!fldr!"
    move "%%a" "!fldr!"
)
popd
pause
exit

But it creates a folder with the first four characters if the file has more than four characters.

What I want to do is that the batch file evaluates the file name, stops at separator string  CHK# and moves the file to the folder based on first and last name in file name left to  CHK#.


Solution

  • A PowerShell solution using a RegEx to get the file name parts in front of CHK# by using
    a lookahead zerolength assertion

    ## Q:\Test\2019\04\01\SO_55462032.ps1
    
    Pushd "C:\Folder"
    
    Get-ChildItem *CHK#* -File | Where Name -match '^(.*)(?= CHK#)' | ForEach-Object {
       If(!(Test-Path $Matches[1])){New-Item -ItemType Directory -Name $Matches[1]}
       $_ | Move-Item -Destination $Matches[1]
    }
    PopD
    

    Sample output:

    > tree /F
    ├───FirstName
    │       FirstName CHK#654
    │
    ├───FIRSTNAME LASTNAME
    │       FIRSTNAME LASTNAME CHK#123
    │       FIRSTNAME LASTNAME CHK#145
    │
    ├───Firstname Middlename Lastname
    │       Firstname Middlename Lastname CHK#987
    │
    └───Title Firstname MiddleName Lastname
            Title Firsname MiddleName Lastname CHK#159