Search code examples
windowsbatch-filedirectorybatch-rename

Batch: Create folders from filename (substring)


i have loads of files which i want to organize differently. The batch script should create folders with the substring on the left side of the date in the filename.

Files are now named like this:

This_is_my_file_21.01.29_22-00_abc_115.avi
This_is_my_file_20.09.29_21-10_abc_15.avi
This_is_another_file_21.01.29_22-00_abc_55.avi

Pattern:

<Name with unknown number of underscores>_<YY.MM.DD>_<hh-mm>_<string with unknown length>_<number n from 1-999>.avi

Folders should be named like this:

This_is_my_file <- two files will go into this directory
This_is_another_file <- only one file.

The Problem is, how do I get the correct substring for my folder name?

This is what I have so far:

@echo off
setlocal

set "basename=."
for /F "tokens=1* delims=." %%a in ('dir *.avi /B /A-D ^| sort /R') do (
   set "filename=%%a"
   setlocal EnableDelayedExpansion
   

   
   for /F "delims=" %%c in ("!basename!") do if "!filename:%%c=!" equ "!filename!" (
      set "basename=!filename!"
      md "!basename:~0,-23!"
   )
   move "!filename!.%%b" "!basename:~0,-23!"
   for /F "delims=" %%c in ("!basename!") do (
      endlocal
      set "basename=%%c
   )
)

Solution

  • @ECHO OFF
    SETLOCAL
    rem The following settings for the source directory, destination directory, target directory,
    rem batch directory, filenames, output filename and temporary filename [if shown] are names
    rem that I use for testing and deliberately include names which include 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\t w o"
    
    FOR /f "delims=" %%b IN ('dir /b /a-d "%sourcedir%\*.avi" ' ) DO (
     SETLOCAL ENABLEDELAYEDEXPANSION
      CALL :countus "%%b"
      IF DEFINED subdir (
       MD "!subdir!" 2>NUL
       ECHO MOVE "%sourcedir%\%%b" "%sourcedir%\!subdir!\"
      ) ELSE (
       ECHO Failed pattern check %%b
      )
     ENDLOCAL
    )
    GOTO :EOF
    
    :: count number of underscores before pattern YY.MM.DD_hh-mm
    :countus
    SET /a ucount=0
    :countusloop
    SET /a ucount+=1
    SET /a scount=ucount+1
    FOR /f "tokens=%ucount%,%scount%delims=_" %%q IN ("%~1") DO SET "str1=%%q"&SET "str2=%%r"
    IF NOT DEFINED str2 SET "subdir="&GOTO :EOF 
    :: is %str1%.%str2:-=.%. of form np.np.np.np.np where np is a number-pair?
    SET "candidate=%str1%.%str2:-=.%."
    FOR /L %%c IN (10,1,99) DO IF DEFINED candidate SET "candidate=!candidate:%%c.=!"&IF NOT DEFINED candidate GOTO success
    FOR /L %%c IN (0,1,9) DO IF DEFINED candidate SET "candidate=!candidate:0%%c.=!"&IF NOT DEFINED candidate GOTO success
    GOTO countusloop
    :success
    SET "subdir=%~1"
    FOR /f "delims=:" %%e IN ("!subdir:_%str1%_%str2%=:!") DO SET "subdir=%%e"
    GOTO :eof
    

    The "move" command is merely echoed for verification. Remove the echo from echo move to actually move the files.