【发布时间】:2021-03-06 11:36:39
【问题描述】:
我想让脚本做什么:
我需要通过删除 Handbrake 添加的 -1 后缀来重命名 Handbrake 创建的 .mkv 视频文件,然后删除具有完全相同名称(减去 -1)的原始源视频文件,但也可能是不同的文件扩展名。
一些注意事项:
- 我正在使用 Windows SendTo 将源文件作为外部变量传递给脚本
- 源视频文件和文件目录可能包含空格、& 和括号
- 源文件可能具有不同的扩展名,例如 .mp4、.mkv、.wmv、.mov
- 文件的目录位置不固定
- 批处理脚本不会与文件在同一目录中执行
- 使用NirCmd的
clonefiletime命令将原文件的时间属性复制到新文件中 - 使用 NirCmd 的
moverecyclebin命令将文件移动到回收站而不是使用 del 命令
示例和预期行为
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
在这种情况下,Test File & final (test).mp4 的时间属性被复制到Test File & final (test)-1.mkv,然后Test File & final (test).mp4 被移动到回收站,最后Test File & final (test)-1.mkv 被重命名为Test File & final (test).mkv。
我目前拥有的代码:
@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
问题:
脚本对于包含与号的文件名失败,我认为空格存在问题,因为 Windows 会自动在文件路径和包含它们的名称周围添加引号。
例如,"C:\Test test\Test File & final (test)-1.mkv" 在使用 Windows SendTo 时被自动引用,而我用双引号将整个变量括起来会解决 & 号问题,但它会变成 SET "source="C:\Test test\Test File & final (test)-1.mkv"",这也会破坏脚本。
我也尝试过 SET "source=%~1",但它会破坏第一个 FOR 循环 - 下面的示例输出:
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"
)
代码很乱,因为我对编码一无所知,但我很感激任何帮助。
【问题讨论】:
-
使用
set "source=%~1"删除潜在的引号,然后使用for %%z in ("!source!") do (…);因为你从不使用普通的%%z,但总是使用一些~-修饰符(如%%~nz),此时引号再次被删除...... -
感谢 aschipfl,这实际上是一个相对简单的修复。
标签: windows batch-file cmd rename