Reputation: 158
What I want the script to do:
I need to rename a .mkv video file created by Handbrake by removing the -1 suffix, which Handbrake adds, then delete the original source video file which has the exact same name (minus the -1), but also potentially a different file extension.
Some caveats:
clonefiletime
command to copy the original file's time attributes to the new filemoverecyclebin
command to move the file to recycle bin rather than using del commandExample and expected behaviour
Directory: C:\Test test\
Files:
Test File & final (test)-1.mkv - Handbrake created file I want to rename
Test File & final (test).mp4 - original source file I want to delete
Test File & final.mp4
Test File.mp4
Otherfile.mp4
Another File.wmv
DifferentFile (1234).mkv
In this scenario, the time attributes of Test File & final (test).mp4
are copied over to Test File & final (test)-1.mkv
, Test File & final (test).mp4
is then moved to the recycle bin and finally Test File & final (test)-1.mkv
is renamed to Test File & final (test).mkv
.
Code I have so far:
@ECHO Off
SETLOCAL EnableDelayedExpansion
SET source=%1
FOR %%z IN (!source!) DO (
SET fpath=%%~dpz
SET filename=%%~nz
SET ext=%%~xz
SET fileprune=!filename:~0,-2!
)
(
ENDLOCAL
SET "fpath=%fpath%"
SET "filename=%filename%"
SET "fileprune=%fileprune%"
SET "ext=%ext%"
SET "fixed=%fileprune%%ext%"
)
FOR /f "delims=" %%a IN ('dir /b "%fpath%" ^| findstr /L /E /C:"%fileprune%.mp4" /C:"%fileprune%.wmv" /C:"%fileprune%.mkv" /C:"%fileprune%.mov"') DO (
REM use NirCmd to copy the timestamp of the original file over to new file
nircmdc clonefiletime "%fpath%%%a" %source%
REM use NirCmd to move old file to recycle bin instead of del command as a failsafe measure
nircmdc moverecyclebin "%fpath%%%a"
)
FOR %%b IN ("%fixed%") DO (
REN %source% "%%~nxb"
)
EXIT
The problem:
The script fails for filenames which contain ampersands and I believe there's an issue with spaces, in that Windows automatically adds quotes around the file path and name which contains them.
For example "C:\Test test\Test File & final (test)-1.mkv"
is quoted automatically when using Windows SendTo and I read surrounding the entire variable with double quotes would resolve the ampersand issue, but it would become SET "source="C:\Test test\Test File & final (test)-1.mkv""
which also breaks the script.
I've also tried doing SET "source=%~1"
, but it then breaks the first FOR loop - example output below:
C:\Test test>(
SET fpath=C:\
SET filename=Test
SET ext=
SET fileprune=!filename:~0,-2!
)
C:\Test test>(
SET fpath=C:\Test test\test\
SET filename=Test
SET ext=
SET fileprune=!filename:~0,-2!
)
C:\Test test>(
SET fpath=C:\Test test\
SET filename=File
SET ext=
SET fileprune=!filename:~0,-2!
)
C:\Test test>(
SET fpath=C:\Test test\
SET filename=&
SET ext=
SET fileprune=!filename:~0,-2!
)
C:\Test test>(
SET fpath=C:\Test test\
SET filename=final
SET ext=
SET fileprune=!filename:~0,-2!
)
C:\Test test>(
SET fpath=C:\Test test\
SET filename=(test)-1
SET ext=.mkv
SET fileprune=!filename:~0,-2!
)
C:\Test test>(
ENDLOCAL
SET "fpath=C:\Test test\"
SET "filename=(test)-1"
SET "fileprune=(test)"
SET "ext=.mkv"
SET "fixed=(test).mkv"
)
The code is a mess since I know nothing about coding, but I'd appreciate any help.
Upvotes: 0
Views: 436
Reputation: 2951
by doublequoting the definition of all variables, and manipulation of the environment properties troublesome characters can be processed within a for loop.
by assigning the initial value to the variable in an environment where delayed expansion is disabled, troublesome characters can be preserved including !
Delayed expansion can then be enabled to safely perform substring modification regardless of poison characters.
an example:
@Echo off & CD "%~dp0"
Setlocal DisableDelayedexpansion
Set "demofile=test!^!&~.txt"
Break >"%demofile%"
For %%G in ("test!*.txt")Do (
Set "Filepath=%%~nG"
Call :Sub Filepath
)
Set Filepath
del "%demofile%"
Goto :Eof
:sub
Set /A i+=1 + 0
Setlocal EnableDelayedexpansion
Set "_tmp=!%1!"
Set "_tmp=!_tmp:&=^&!"
Endlocal & Set "%1[%i%]=%_tmp%"
Set %1=
Goto :Eof
Upvotes: 2
Reputation: 158
Thanks to aschipfl and T3RR0R for pointing out I was missing double quotes around some variables.
Revised code:
@ECHO Off
SETLOCAL EnableDelayedExpansion
SET "source=%~1"
FOR %%z IN ("!source!") DO (
SET nsource=%%~dpnxz
SET fpath=%%~dpz
SET filename=%%~nz
SET ext=%%~xz
SET fileprune=!filename:~0,-2!
)
(
ENDLOCAL
SET "nsource=%nsource%"
SET "fpath=%fpath%"
SET "filename=%filename%"
SET "fileprune=%fileprune%"
SET "ext=%ext%"
SET "fixed=%fileprune%%ext%"
)
FOR /f "delims=" %%a IN ('dir /b "%fpath%" ^| findstr /L /E /C:"%fileprune%.mp4" /C:"%fileprune%.wmv" /C:"%fileprune%.mkv" /C:"%fileprune%.mov"') DO (
REM use NirCmd to copy the timestamp of the original file over to new file
nircmdc clonefiletime "%fpath%%%a" "%nsource%"
REM use NirCmd to move old file to recycle bin instead of del command as a failsafe measure
nircmdc moverecyclebin "%fpath%%%a"
)
FOR %%b IN ("%fixed%") DO (
REN "%nsource%" "%%~nxb"
)
EXIT
Upvotes: 0