Home > Net >  Organize files into folders then subfolders based on filenames
Organize files into folders then subfolders based on filenames

Time:05-20

A set of files have "Main Folder Name" (explicit) and a SubFolderName (hinted) in their filenames.

The intention is to just have them organized in new folders by "Main Folder Name" and SubFolderName then have all files moved to their corresponding new folders using batch script.

Example:

|>SourceDirectory

|>Main Folder Name (0001) S01E01 - FileDescription.bmp
|>Main Folder Name (0001) S01E01 - FileDescription.srt
|>Main Folder Name (0001) S01E02 - FileDescription.bmp
|>Main Folder Name (0001) S01E03 - FileDescription.bmp
|>Main Folder Name (0001) S01E03 - FileDescription.srt
|>Main Folder Name (0007) S03E01 - FileDescription.jpg
|>Main Folder Name (0007) S03E02 - FileDescription.png
|>Main Folder Name (0007) S03E03 - FileDescription.srt
|>Main Folder Name (0012) S25E01 - FileDescription.ico
|>Main Folder Name (0012) S25E02 - FileDescription.txt

Intended Outcome

|>SourceDirectory

|>Main Folder Name (0001)
    |>SubFolderName 1
        |>Main Folder Name (0001) S01E01 - FileDescription.bmp
        |>Main Folder Name (0001) S01E01 - FileDescription.srt
        |>Main Folder Name (0001) S01E02 - FileDescription.bmp
        |>Main Folder Name (0001) S01E03 - FileDescription.bmp
        |>Main Folder Name (0001) S01E03 - FileDescription.srt

|>Main Folder Name (0007)
    |>SubFolderName 3
        |>Main Folder Name (0007) S03E01 - FileDescription.jpg
        |>Main Folder Name (0007) S03E02 - FileDescription.png
        |>Main Folder Name (0007) S03E03 - FileDescription.srt

|>Main Folder Name (0012)
    |>SubFolderName 25
        |>Main Folder Name (0012) S25E01 - FileDescription.ico
        |>Main Folder Name (0012) S25E02 - FileDescription.txt

Spent days trying and taking tips from other posts but my grasp in batch commands proved to be just too basic for this task.

Here's my working pseudo code:

1. Take first file
2. Search for the string pattern S??E?? to give away:

    FolderName = All chars on the left of S??
    SubFolderNumber = NumericValue of ?? in S??

3. MakeDir \FolderName\"SubFolderName "   SubFolderNumber
4. Move the file to that new subfolder in step #3
5. Recurse and do steps 1-4 to each file until the end of the list

Step #2 may be too simple for the experts in this community but it is not keeping my hands from pulling my hair. :D

Would really appreciate help from anyone who could spare the time and let me keep the little hair I have left.

CodePudding user response:

Painfully came up with a ver1.0.

Not fool-proof yet but does the job for now. Kind of slow though. Needs some tuning up from a kind expert out there, maybe a far better approach or even an overhaul.

Your kind suggestions are very much welcome.

@ECHO OFF
SETLOCAL EnableDelayedExpansion
FOR %%a in (*) DO (
    SET FileName=%%~na
    CALL:findString FileName ") S" pos
    SET /A pos=pos 1
    SET /A pos2=pos 2
    CALL SET "NewFolderName=%%FileName:~0,!pos!%%"
    CALL SET "NewSubFolderNumber=%%FileName:~!pos2!,2%%"
    SET /A NewSubFolderNumber=NewSubFolderNumber
    SET NewSubFolder="%%~pa!NewFolderName!\SubFolderName !NewSubFolderNumber!\"
    SET str="%%~fa" !NewSubFolder!
    MD !NewSubFolder!
    MOVE !str!
)

Seek and ye shall find. Found this missing link somewhere in the net just in time to save my remaining lock of hair. (Anyone knows why there isn't a built-in INSTR() function in the first place?)

:findString -- returns position of first occurrence of a string in another string, case sensitive, maximum string length is 1023 characters
::          -- %~1: in - varible name of a string to be searched
::          -- %~1: in - string to be found
::          -- %~3: out- return variable name, will be set to position or undefined if string not found
:credit belongs to
:$source http://www.dostips.com
:Posted By: DosItHelp
:Expert
:Posts: 239
:Joined: 18 Feb 2006 19:54

SETLOCAL ENABLEDELAYEDEXPANSION
set "pos="
set "str=!%~1!"
for /L %%a in (0,1,1023) do (
   set "s=!str:~%%a!"
   if not defined pos if "%~2!s:*%~2=!"=="!s!" set "pos=%%a"
)
ENDLOCAL & IF "%~3" NEQ "" SET "%~3=%pos%"
GOTO:EOF

Hope this can help others.

CodePudding user response:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION 

rem The following setting for the source directoryis a name
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.

SET "sourcedir=u:\your files"
PUSHD "%sourcedir%"

FOR /L %%s IN (0,1,9) DO FOR /L %%t IN (0,1,9) DO IF EXIST "* S%%s%%tE*" (
 FOR /L %%e IN (0,1,9) DO FOR /L %%f IN (0,1,9) DO IF EXIST "* S%%s%%tE%%e%%f -*" (
  FOR /f "delims=" %%b IN ('dir /b /a-d "* S%%s%%tE%%e%%f -*"') DO (
   SET "fullname=%%b"
   FOR /f "tokens=1,2delims=:" %%q IN ("!fullname: S%%s%%tE%%e%%f =:!") DO (
    IF %%s==0 (
rem     MD "%%q\%%t" 2>nul
rem     MOVE "%%b" "%%q\%%t\" >nul
     ECHO MD "%%q\%%t"
     ECHO MOVE "%%b" "%%q\%%t\"
    ) ELSE (
rem     MD "%%q\%%s%%t" 2>nul
rem     MOVE "%%b" "%%q\%%s%%t\" >nul
     ECHO MD "%%q\%%s%%t"
     ECHO MOVE "%%b" "%%q\%%s%%t\"
    )

   )
  )
 )
)

dir/s

popd

GOTO :EOF

This batch is designed to REPORT what it intends to do, and should be tested against a test directory before applying it to your live data.

When you are satisfied with the results, remove the rem comment keyword from the two md and move lines to activate. The echo lines may be removed if desired.

The dir/s at the end simply shows the result.

The key here is the string S??E??.

by using %%s and %%t each set to 0..9 in turn, we can see whether a file named * S00E*..* S99E* exists. If such a file exists, repeat the recipe using %%e and %%f to find * S00E00 -*..* S99E99 -*.

Then grab a list of the filenames using /b for names-only and /a-d for no directorynames, matching the specific S??E?? string calculated, and assign to %%b.

We need to analyse %%b so need delayedexpansion and transfer to a regular variable fullname to do so.

Since the filename does not contain :, simply replace the S??E?? detected by : and use for/f tokens and delims options to break the name at the S??E?? -> : %%r is set to the part after and %%q to that before. %%r is not used in this process.

Then it's a matter of establishing the subdirectory in %%q and the sub-subdirectory in %%s or %%s%%t.

The 2>nul suppresses the directory exists messages created if a directory is re-created, and the >nul on the move command suppresses the 1 file(s) moved message.

  • Related