Move files to a subfolder sharing part of the file name Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
JKnight_xbt33
Posts: 135
Joined: 18 Sep 2019, 02:06

Move files to a subfolder sharing part of the file name

30 Dec 2019, 15:30

Dear Broskis & Broskas.

I have a starting folder C:\Users\JK\Documents\reports PDFs. This contains pdf files e.g. 2223-report.pdf

I have a destination folder W:\Departments\QA\cases containing sub folders, for example W:\Departments\QA\cases\2201 - 2300\2223

I want to move the PDFs from my starting folder to the destination folder but inside subfolders in this destination folder which share part of the file name.

For example 2223-report.pdf would be moved to W:\Departments\QA\cases\2201 - 2300\2223

I read up filemove and tried to tweak the example script for use with subfolders but feeling stuck. How could I tweak my code to move files into subfolders?

Appreciated
JK
-----------

Code: Select all

ErrorCount := MoveFilesAndFolders("C:\Users\JK\Documents\reports PDFs\*.pdf", "W:\Departments\QA\cases")
if (ErrorCount != 0)
    MsgBox %ErrorCount% files/folders could not be moved.

MoveFilesAndFolders(SourcePattern, DestinationFolder, DoOverwrite = false)
; Moves all files and folders matching SourcePattern into the folder named DestinationFolder and
; returns the number of files/folders that could not be moved. This function requires [v1.0.38+]
; because it uses FileMoveDir's mode 2.
{
    if (DoOverwrite = 1)
        DoOverwrite := 2  ; See FileMoveDir for description of mode 2 vs. 1.
    ; First move all the files (but not the folders):
    FileMove, %SourcePattern%, %DestinationFolder%, %DoOverwrite%
    ErrorCount := ErrorLevel
   
    return ErrorCount
}
JKnight_xbt33
Posts: 135
Joined: 18 Sep 2019, 02:06

Re: Move files to a subfolder sharing part of the file name  Topic is solved

08 Jan 2020, 12:53

Got the answer to my question but I had to use a batch/cmd script from stack exchange. Its quite complicated to be honest but the person was kind enough to explain how it all works. See my thread for this in the stackoverflow link below:

https://stackoverflow.com/questions/59546150/move-files-into-a-subfolder-of-a-destination-directory/59564278?noredirect=1#comment105399746_59564278

here is the full batch/cmd script which moves files into a subfolder:

Code: Select all

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_SOURCE=C:\Users\JK\Documents\reports PDFs" & rem // (source directory; `.` or `` is current, `%~dp0.` is script parent)
set "_TARGET=W:\Departments\QA\cases" & rem // (target directory; `.` or `` is current, `%~dp0.` is script parent)
set "_SUBDIR=#"      & rem // (set to non-blank value in order to create individual sub-directories)
set "_FMASK=????*.pdf"    & rem // (pattern to match source files)
set "_DMASK=???? - ????*" & rem // (pattern to match target directories)
set "_FFIL1=^[0123456789][0123456789][0123456789][0123456789] .*\.pdf$" & rem // (filter 1 for source files)
set "_FFIL2=^[0123456789][0123456789][0123456789][0123456789]\.pdf$"    & rem // (filter 2 for source files)
set "_DFIL1=^[0123456789][0123456789][0123456789][0123456789] - [0123456789][0123456789][0123456789][0123456789] .*$"
set "_DFIL2=^[0123456789][0123456789][0123456789][0123456789] - [0123456789][0123456789][0123456789][0123456789]$"

rem // Change into source directory:
pushd "%_SOURCE%" && (
    rem // Iterate through all files matching the specified pattern and filters:
    for /F "eol=| delims=" %%F in ('
        dir /B /A:-D-H-S "%_FMASK%" ^| findstr /I /R /C:"%_FFIL1%" /C:"%_FFIL2%"
    ') do (
        rem // Store full path of currently iterated file:
        set "FILE=%%~fF"
        rem // Extract the leading numeric part of the file name:
        for /F "eol=| delims= " %%N in ("%%~nF") do (
            rem // Store the numeric part:
            set "NUM=%%N"
            rem /* Remove any leading zeros from the numeric part of the file name, because
            rem    such cause the number to be unintentionally interpreted as octal: */
            set /A "INT=0" & for /F "eol=| tokens=* delims=0" %%Z in ("%%N") do 2> nul set /A "INT=%%Z"
        )
        rem // Change into target directory:
        pushd "%_TARGET%" && (
            rem // Iterate through all directories matching the specified pattern and filters:
            for /F "eol=| delims=" %%D in ('
                cmd /V /C 2^> nul dir /B /A:D-H-S "!_DMASK:|=%%I!" ^| findstr /I /R /C:"%_DFIL1%" /C:"%_DFIL2%"
            ') do (
                rem // Store name of currently iterated directory:
                set "TDIR=%%D"
                rem // Extract first (from) and second (to) numeric parts of directory names:
                for /F "eol=| tokens=1-2 delims=- " %%S in ("%%D") do (
                    rem // Remove any leading zeros from first (from) numeric part:
                    set /A "FRM=0" & for /F "eol=| tokens=* delims=0" %%Z in ("%%S") do set /A "FRM=%%Z"
                    rem // Remove any leading zeros from second (to) numeric part:
                    set /A "TOO=0" & for /F "eol=| tokens=* delims=0" %%Z in ("%%T") do set /A "TOO=%%Z"
                )
                rem // Toggle delayed variable expansion to avoid trouble with `!`:
                setlocal EnableDelayedExpansion
                rem /* Do integer comparisons to check whether the numeric part of the file name
                rem    lies within the range given by the directory name (from/to): */
                if !INT! geq !FRM! if !INT! leq !TOO! (
                    rem // Numeric part of file name lies within range, hence try to move file:
                    if defined _SUBDIR (
                        2> nul md "!TDIR!\!NUM!"
                        ECHO move "!FILE!" "!TDIR!\!NUM!\"
                    ) else (
                        ECHO move "!FILE!" "!TDIR!\"
                    )
                )
                endlocal
            )
            rem // Return from target directory:
            popd
        )
    )
    rem // Return from source directory:
    popd
)

endlocal
exit /B
User avatar
flyingDman
Posts: 2821
Joined: 29 Sep 2013, 19:01

Re: Move files to a subfolder sharing part of the file name

08 Jan 2020, 18:34

A solution in AHK is significantly less complicated than that! I am surprised that nobody responded to your request. The following should accomplish it in AHK.
In the destination folder it will first create the xxxx - yyyy subfolders and the zzzz sub-subfolders as needed and concurrently copy / move all files from sourcepath to destpath/xxxx - yyyy/zzzz. For testing purposes in used filecopybut this can be replaced with the filemove when you are satisfied.

Code: Select all

sourcepath := "C:\Users\xxxx\reports\"
destpath := "C:\Users\xxxx\cases\Sortfolder\"

Loop, Files, %sourcepath%*.pdf
	{
	regexmatch(A_LoopFileName,"(\d+)",match)
	num := match1
	FileCreateDir, % destpath . floor(num/100) "01 - " ceil(num/100) "00\" num
	filecopy, %A_LoopFileFullPath%,% destpath . floor(num/100) "01 - " ceil(num/100) "00\" num "\" A_LoopFileName         
	tooltip, % "creating " destpath . floor(num/100) "01 - " ceil(num/100) "00\" num "\" A_LoopFileName, %a_screenwidth%, % a_screenheight - 50 
	}
tooltip	
Msgbox Done!
return
14.3 & 1.3.7
JKnight_xbt33
Posts: 135
Joined: 18 Sep 2019, 02:06

Re: Move files to a subfolder sharing part of the file name

17 Jan 2020, 08:43

Thanks for this @flyingDman I'll bear this much simpler and easier to understand AHK code in mind for the next time.
:D

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot], GEOVAN, unnamed9710 and 284 guests