Naith Bryen
Naith Bryen

Reputation: 41

Batch to create folder and move files with first 9 characters matching

I am just wondering if I have modified the source and target location appropriately on using code posted in answer on How to copy files into folders based on first 15 characters of file and folder name?

I can't get it to run. I am just trying to create a folder named the first 9 characters and move all files with matching first 9 characters into that folder.

@echo off 
setlocal EnableExtensions 
set "SourceFolder=C:\PRASINUS\July #2" 
set "TargetFolder=C:\PRASINUS\Test 1"

rem Call subroutine CopyFile for each non hidden and 
rem non system file found in specified source folder 
rem and then exit processing of this batch file.

for %%I in ("%SourceFolder%*") do call :CopyFile "%%~fI"

endlocal 
goto :EOF

rem This is a subroutine called for each file in source folder. 
rem It takes the first 9 characters from each file name passed 
rem to this subroutine via first parameter and search for a 
rem folder in target folder starting with same 9 characters. 
rem If such a folder is found, the file is copied to this folder 
rem and the subroutine is exited. 
rem Otherwise a new folder is created for the file and if 
rem this is indeed successful, the file is copied into the 
rem newly created folder with an appropriate message.

:CopyFile 
set "FileName=%~n1" 
set "DirectoryName=%FileName:~0,9%" 
for /D %%D in ("%TargetFolder%\%DirectoryName%*") do ( 
    copy /B /Y %1 /B "%%~D\" >nul 
    goto :EOF
)

set "NewFolder=%TargetFolder%\%DirectoryName%_new" 
md "%NewFolder%" 
if exist "%NewFolder%\" ( 
    echo Created new folder: %NewFolder% 
    copy /B /Y %1 /B "%NewFolder%\" >nul 
    goto :EOF 
)

echo Failed to create folder: %NewFolder%
echo Could not copy file: %1 
goto :EOF

Upvotes: 3

Views: 1748

Answers (3)

E-Starlink Support
E-Starlink Support

Reputation: 1

All help with this goes to @XionicFire he reworked the whole of this code I'm just posting it for others to use/benefit:

This code comes from a mix of several different people @PrahladDixit & @Compo, the code was not working we couldn't tell why after a LOT of search seems it suffered the usual... "a pro wrote this so no one understands what he did" syndrome, where us worms cannot figure it out, we remade it and organized it so normal human "worms" can understand what its doing and made it a little friendlier so its easier to mod and change as needed, we hope this helps others, works great in windows 11

@ECHO OFF
ECHO This file will create Individual folders inside the current folder using the following Parameters and sort all *.JPG files in current directory accordingly
REM To change target or source directory simply type it in the variable field
SET "SRC=%~dp0"
SET "SRC=%SRC:~0,-1%"
SET "DST=%~dp0"
SET "DST=%DST:~0,-1%"
ECHO. 
REM For Diagnostics & Troubleshooting Purposes
ECHO Source: %SRC%
ECHO Destination: %DST%
ECHO Characters: 19
ECHO Where: %SystemRoot%\System32\where.exe "%SRC%":*.jpg
ECHO. 
ECHO To Cancel this operation press CTRL-C
PAUSE
SetLocal EnableDelayedExpansion
If Not Exist "%SRC%\" (Exit/B) Else If Not Exist "%DST%\" Exit/B
For /F "Delims=" %%A In ('%SystemRoot%\System32\where.exe "%SRC%":*.jpg') Do (
    SET "FNX=%%~nA"
REM Replace 19 for the number of characters from the start of the filename you wish to use as Base for folder creation
    SET "FNX=!FNX:~,19!
REM For Diagnostics & Troubleshooting Purposes
REM ECHO !DST!\!FNX!\
    If Not Exist "!DST!\!FNX!\" (MD "!DST!\!FNX!" 2>NUL
        If ErrorLevel 1 ECHO Unable to create directory !DST!\!FNX!)
    If Exist "!DST!\!FNX!\" (MOVE /Y "%%A" "!DST!\!FNX!">NUL 2>&1
        If ErrorLevel 1 ECHO Unable to move %%A to !DST!\!FNX!)
    )
ECHO ************************ DONE ************************
PAUSE
REM Use in the case of running multiple scripts in a row
REM EXIT/B

Upvotes: 0

Compo
Compo

Reputation: 38654

An alternative to the example script you found, (minimum requirement Windows Vista):

@Echo Off 

Set "SRC=C:\PRASINUS\July #2"
Set "DST=C:\PRASINUS\Test 1"

SetLocal EnableDelayedExpansion
If Not Exist "%SRC%\" (Exit/B) Else If Not Exist "%DST%\" Exit/B
For /F "Delims=" %%A In ('Where "%SRC%":?????????*.*') Do (Set "FNX=%%~nA"
    If Not Exist "%DST%\!FNX:~,9!\" (MD "%DST%\!FNX:~,9!" 2>Nul
        If ErrorLevel 1 Echo Unable to create directory %DST%\!FNX:~,9!)
    If Exist "%DST%\!FNX:~,9!\" (Move /Y "%%A" "%DST%\!FNX:~,9!">Nul 2>&1
        If ErrorLevel 1 Echo Unable to move %%A to %DST%\!FNX:~,9!))
Timeout -1
Exit/B

The above is for the first nine characters as requested. To change to fifteen characters replace each instance of 9 with 15 and match the quantity of sequential ?'s to 15 too.

Upvotes: 0

Magoo
Magoo

Reputation: 80123

Code formatting: cut-and-paste your code;select it and press {} in the bar above the edit-box to indent each line 4 spaces (which indicates 'code')

You need to include \ between %SourceFolder% and * in "%SourceFolder%*" to indicate to cmd that you want all files (*) within the directory %SourceFolder%, not files matching "%SourceFolder%+anystring"

The directoryname variable is set correctly (but are you worried about names shorter than 9 characters?)

You then appear to want to check on the presence of any directory starting %directoryname% and copy the filename found to the first such name found; if no directory found, create a new one; check it was created and either copy or notify as appropriate.

All of which appears OK. If this is intended to have a target on a FAT-formatted drive however, you should be aware that the directorynames are not necessarily returned in alphabetical order, so directory_old may appear before directory_new if both exist.

I must congratulate you on the amount of documentation you've used. It's my preference to use :: in place of rem as I find it makes for easier reading - you're not "reading" the rem "word" as the eye ignores the :: since it's not a word. Note that ::-comments may not be used within a code-block (parenthesised series of statements)

Upvotes: 3

Related Questions