Reputation: 538
So I have a set of files that look something like this:
Bob - Test Name - 1.txt
Bob - Test Name - 2.txt
Bob - Test Name - 3.txt
Sam- Foo Name - 1.txt
Sam- Foo Name - 2.txt
Sam- Foo Name - 3.txt
Phil - 1.txt
Phil - 2.txt
Phil - 3.txt
Phil 2 - 1.txt
Phil 2 - 2.txt
Phil 2 - 3.txt
Simply, the pattern is something like this:
[WHATEVER] - #.txt
[WHATEVER](space)-(space)(number).extension
I would like to do the following:
So far, everything I have tried, I have failed. Not knowing how to troubleshoot or see what batch is doing, I am shooting in the wind.
I would like this to be extension agnostic as I have various file types (mp3, etc) for this scenario (set extension at the beginning of the batch file).
Upvotes: 0
Views: 1314
Reputation: 11151
This piece of code will work on files which match * - #.*
, where #
is a number and *
may contain multiple (space)-(space)
- only first (space)-(space)(number).
is accounted.
SETLOCAL ENABLEDELAYEDEXPANSION
REM Call process for each file that match "name - number.extension"
FOR %%f IN ("* - *.*") DO CALL :process "" "%%f"
GOTO :EOF
REM Recursive function process: accepts two arguments: prefix and filepart
REM process checks if number part of supplied filename is a number.
REM prefix is string already checked but mismatched number. Example:
REM Call 1: "" "a - b - c - 1.ext" mismatch ("b - c - 1" is not a number)
REM Call 2: "a -" " b - c - 1.ext" mismatch ("c - 1" is not a number)
REM Call 3: "a - b -" " c - 1.ext" match ("1" is a number)
:process
REM Break filepart at first "-"
FOR /F "TOKENS=1,* DELIMS=-" %%i IN (%2) DO (
REM If after "-" is empty, file mismatch (something like "abc.ext-")
IF "%%j" == "" GOTO :EOF
REM Break part after "-" at first "."
FOR /F "TOKENS=1,* DELIMS=." %%n IN ("%%j") DO (
REM Multiply part before "." by 1. If part is not number, will evaluate to 0.
SET /A "number=1*%%n"
REM Check if rebuilt part afte "-" match using parsed number
IF "%%j" == " !number!.%%o" (
REM Matched, so do whatever is needed
ECHO Moving "%~1%~2" to "%~1%%i"...
IF NOT EXIST "%~1%%i" MD "%~1%%i"
REM MOVE "%~1%~2" "%~1%%i"
REM Exit function
GOTO :EOF
)
)
REM File part didn't match, so recall process shifting part before "-" to prefix
REM and using part after "-" as filepart.
CALL :process "%~1%%i-" "%%j"
)
It may leak on, eg, name1 - 1. name2 - 2.txt
, creating folder name1
instead of name1 - 1. name2
.
EDIT: Added comments. Corrected typo on CALL :process "%~1%%i-" "%%j"
Upvotes: 0
Reputation: 37569
@echo off &SETLOCAL
SET "startfolder=c:\test\test"
CD /d "%startfolder%"
FOR %%X IN (*.txt) DO (
FOR /f "delims=" %%a IN ('echo(%%~NX^|sed -r "s/^(.*)\s-\s[0-9]+$/\1/"') DO (
IF NOT EXIST "%%~a\" MD "%%~a"
MOVE "%%~X" "%%~a"
)
)
Upvotes: 1
Reputation: 6630
I'm not entirely sure what you want, but I think this will work:
setlocal enabledelayedexpansion
cd C:\...[path to folder]
set /a count=0
for /r "delims=-" %%a in (*) do (
set /a count=!count!+1
for /l %%z in (1,1,!count!) do (
if %%a equ !%%z! ( move %%a C:\...[out put folder collection]\!%%z!\%%a%%b
) else ( set !count!=%%a)
)
)
Folder Collection
> 1
>> name - 1.txt
>> name - 2.txt
>> name - 3.txt
> 2
>> name - 1.txt
>> name - 2.txt
>> name - 3.txt
> 3
>> name - 1.txt
>> name - 2.txt
>> name - 3.txt
I'm pretty sure that will work. Haven't tested it, so if you find or get any errors tell me.
Note: This will only accept one "-" in the file name. Having more then one means it will exclude the extension.
Also, I havn't made it work for specified extensions. Making another answer, this time using forfiles
where you can specify the extension.
Mona
Upvotes: 0