Reputation: 415
I want to create folders based on file names that look like this:
file with words 01.wav
file with words 02.wav
file with words 03.wav
file with more words 01.wav
file with more words 02.wav
...
the tree should look like this
Folder
|----file with words
|----file with words 01.wav
|----file with words 02.wav
|----file with words 03.wav
|----file with more words
|----file with more words 01.wav
|----file with more words 02.wav
and the files within should keep their original name How can I address the last whitespace before each number? I can't specify a fixed value for "tokens" because the position of the last whitespace varies from file to file. This was my approach:
FOR /f "tokens=1*" %%a IN (
'dir /b /a-d "* *.wav"'
) DO (
ECHO MD %%a
ECHO MOVE "%%a %%b" .\%%a\
)
PAUSE
-> ECHO
to debug the result
Upvotes: 1
Views: 2165
Reputation: 130819
Here is a version that uses JREPL.BAT - a hybrid JScript/batch utility that performs regular expression text replacements.
The advantages of this solution are that it only attempts to move .wav files whose name matches {baseName}{space}{digit}{digit}, and it will not move files if it cannot create the {baseName} folder because file {baseName} already exists. These features could be added to the pure batch solutions already posted. However, I find it easier to build a robust solution via JREPL.BAT.
@echo off
for /f "tokens=1,2 delims=:" %%A in (
'dir /b "* ??.wmv" ^| jrepl "(.+?) +\d\d\.wmv$" "$1+':'+$0" /i /jmatch'
) do (
if not exist "%%A\" if not exist "%%A" (
md "%%A"
) else echo Can't create folder "%%A" because a file exists with that name
if exist "%%A\" move "%%B" "%%A" >nul
)
Upvotes: 0
Reputation: 70923
@echo off
setlocal enableextensions disabledelayedexpansion
for %%a in (*.wav) do (
set "filename=%%~na"
setlocal enabledelayedexpansion
for %%b in ("::\!filename: =\!\..") do ( endlocal & set "filename=%%~pnxb" )
setlocal enabledelayedexpansion
for /f "tokens=*" %%b in ("!filename:\= !") do (
endlocal
if not exist "%%b\" md "%%b"
if exist "%%b*.wav" move /y "%%b *.wav" "%%b"
)
)
The idea behind the code is to iterate over the list of files and for each one, the spaces in it name are replaced with a backslash (file\with\words\01
) so we can use the for
replaceable parameters to query the "parent folder" of the last element (the name without the ending numbers) and later replace the backslashes with spaces to get the final folder name.
The multiple setlocal/endlocal
are included to handle the case of filenames that could include exclamation points (a problematic character when delayed expansion is enabled).
The code tries to move all matching files in each set with only one move
command, but depending on the real names, it is possible that files from other set could also match. To avoid it, the line
if exist "%%b*.wav" move /y "%%b *.wav" "%%b"
should be converted into
move /y "%%a" "%%b\"
so files are moved one by one without problems.
Upvotes: 2
Reputation: 80023
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
PUSHD "%sourcedir%"
FOR /f "delims=" %%a IN (
'dir /b /a-d *.wav '
) DO (
SET "filename=%%a"
SET "dirname=%%a"
CALL :genmove
)
popd
GOTO :EOF
:genmove
IF "%dirname:~-1%" neq " " set "dirname=%dirname:~0,-1%"&goto genmove
set "dirname=%dirname:~0,-1%"
ECHO(MD "%dirname%"
ECHO(MOVE "%filename%" ".\%dirname%\"
GOTO :eof
You would need to change the setting of sourcedir
to suit your circumstances.
The required MD commands are merely ECHO
ed for testing purposes. After you've verified that the commands are correct, change ECHO(MD
to MD
to actually create the directories. Append 2>nul
to suppress error messages (eg. when the directory already exists)
The required MOVE commands are merely ECHO
ed for testing purposes. After you've verified that the commands are correct, change ECHO(MOVE
to MOVE
to actually move the files. Append >nul
to suppress report messages (eg. 1 file moved
)
Simply generate the same name for the file and directory, trim off the last character from the name until that character is a space, trim that off and you have the required dirname and filename.
Upvotes: 0