Search code examples
batch-filecmddirectorymovesubdirectory

How to organize the files, to create folders with names extracted from the file names


I have the following code that works, I use it to group my songs, but I still need more functionality.

@echo off
setlocal enabledelayedexpansion
PushD %~dp0
set "songsPeralbum=2"
set "fcount=0"
set idx=0

for /F "delims=" %%I in ('dir /a-d /o:n /b *.wav') do (
    REM echo Processing %%I
    set /a idx=idx %% songsperalbum +1
    if !idx! equ 1 set /a fcount+=1
    md Album-!fcount! 2>nul
    move "%%I" "Album-!fcount!\"
    REM pause
)

If possible, I need the following to happen:

The song is of the form: Artist name - Song name
  1. I would like the batch file to search for all songs with the same
    Artist Name
  2. to group them in a folder with the name of the FIRST song found from Artist name,
  3. in that folder with the name of the song another folder with the name of the artist should be created,
  4. move the songs, the final files, to the folder with the artist's name.

In the ALBUMS folder I have hundreds of songs:

Artist name1 - Song Name1.wav
Artist name1 - Song Name2.wav
Artist name2 - Song Name1.wav
Artist name2 - Song Name2.wav
Artist name2 - Song Name3.wav
and the list continue ...

I made a folder structure for more clarity. Need to be like this:

───ALBUMS
│   ├───Song Name XXX
│   │   └───Artist Name1
│   │       ├───Artist name1 - Song Name XXX.wav
│   │       └───Artist name1 - Song Name2.wav
│   └───Song Name YYY
│       └───Artist Name2
│           ├───Artist name - Song Name YYY.wav
│           ├───Artist name - Song Name2.wav
│           └───Artist name - Song Name3.wav


The batch file will run in a loop until it finishes all the songs.


Solution

  • @ECHO Off
    SETLOCAL ENABLEDELAYEDEXPANSION
    rem The following settings for the directory names 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"
    SET "destdir=u:\your results"
    SET "tempfile=%temp%\#$#$#$#.$#$"
    
    (
    FOR /f "delims=-" %%e IN (
     'dir /b /a-d "%sourcedir%\*-*" '
     ) DO ECHO %%e
    )>"%tempfile%"
    
    FOR /f "delims=" %%e IN ('SORT /r /unique "%tempfile%"') DO (
     SET "song="
     FOR /f "tokens=1*delims=-" %%b IN ('dir /b /a-d "%sourcedir%\%%e-*" ') DO (
      IF NOT DEFINED song (
       SET "song=%%~nc"
       SET "artist=%%b"
       CALL :trim artist
       CALL :trim song
       MD "%sourcedir%\!song!\!artist!"
      )
      move "%sourcedir%\%%b-%%c" "%sourcedir%\!song!\!artist!"
     )
    )
    
    DEL "%tempfile%"
    
    GOTO :EOF
    
    :trim
    SET "#=!%1!"
    :lead
    IF "%#:~0,1%"==" " SET "#=%#:~1%"&goto lead
    :trail
    IF "%#:~-1%"==" " SET "#=%#:~0,-1%"&goto trail
    SET "%1=%#%"
    GOTO :eof
    

    Always verify against a test directory before applying to real data.

    Create a tempfile containing artists' names only using the - as a delimiter.

    Sort that file in reverse-alphabetical order so that Artist name2 sorts after Artist name2 & Artist name4 and use the undocumented /unique switch to eliminate duplicates.

    Then find each file using the artist's name; use song as a flag since both song and artist need to be trimmed of leading/yrailing spaces. When the artist changes, (first)song is cleared. If song is not assigned, assign it and trim artist and song and create the directory.

    Suppress the error message on the md by appending 2>nul to that line

    Suppress the move report by appending >nul to that line.

    I've fixed the extension-name-in-directory-name problem (set song to %%~nc instead of %%c - treats the string as a filename, & selects just the name part without the extension.)