我正在编写一个批处理脚本单调文件重命名器。基本上,它使所有文件的标题1 2 3 4 ....等等。我已经扩展它以便能够处理不同类型的文件(txt,doc,flv等),但并非一切都正常。
我主要担心的是我已经打破了我以前制作的延迟扩展电话。现在使用!var1!永远不会扩展,或永远不会被识别为变量。
这是我的脚本的详细评论版本
::a monotonic file renamer
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
SET tempfile=temp.txt
SET exttemp=exttemp.txt
if [%1] == [] goto usage
::make sure your dont overwrite something useful
if EXIST %tempfile% (
ECHO Temp file already exists, are you sure you want to delete?
del /P %tempfile%
)
if EXIST %exttemp% (
ECHO EXT Temp file already exists, are you sure you want to delete?
del /P %exttemp%
)
::initialize
SET /a counter=0
SET type=
SET /a ender=%1
::write filenames to tempfile
DIR /B /ON > %tempfile%
::read lines one by one
for /f "usebackq delims=" %%a in (%tempfile%) do (
REM make sure we do not rename any of the working files
if NOT "%%a"=="renamer.bat" (
if NOT "%%a"=="temp.txt" (
if NOT "%%a"=="exttostr.bat" (
SET /a counter+=1
REM get file extension
exttostr %%a > %exttemp%
SET /P type= < %exttemp%
REM housekeeping
del /F %exttemp%
REM rename
ren %%a !counter!.!type!
ECHO Renamed "%%a" to "!counter!.!type!"
)))
REM exit when we have run enough
if "!counter!"=="!ender!" goto exit
)
goto exit
:usage
echo Usage: renamer NUMFILES
:exit
::final housekeeping
DEL temp.txt
我的想法是将我的两个文件renamer.bat(此文件)和exttostr.bat(帮助程序获取文件扩展名)放入文件夹并运行它,它将按字母顺序重命名文件从1到多少我指定的文件。
当我运行代码时,它从不使用标记为延迟扩展的变量,总是将它们保留为“!varname!”,因此它重命名第一个文件“!counter!。!type!”并且因为目录中已存在具有该名称的文件而导致其余的错误。
这让我想到了第二个问题。按字母顺序排序目录列表会导致对编号文件的处理不当。例如列表: “1 7 15 75 120” 排序: “1 120 15 7 75” 我还没有找到解决方法,只是它确实是dir排序的预期结果。我唯一的解决方法是填充前面有足够零的数字。
提前感谢任何见解!
一切都是排序但第二个问题。我想我说话不好。当我接收目录文件名时,我有这个问题,而不是在写出时。所以他们已经需要填补。我希望有其他方法来读取目录并对其进行适当的排序。
我发现的最有希望的是:http://www.dostips.com/DtCodeBatchFiles.php#Batch.SortTextWithNumbers
@ECHO OFF
if "%~1"=="/?" (
echo.Sorts text by handling first number in line as number not text
echo.
echo.%~n0 [n]
echo.
echo. n Specifies the character number, n, to
echo. begin each comparison. 3 indicates that
echo. each comparison should begin at the 3rd
echo. character in each line. Lines with fewer
echo. than n characters collate before other lines.
echo. By default comparisons start at the first
echo. character in each line.
echo.
echo.Description:
echo. 'abc10def3' is bigger than 'abc9def4' because
echo. first number in first string is 10
echo. first number in second string is 9
echo. whereas normal text compare returns
echo. 'abc10def3' smaller than 'abc9def4'
echo.
echo.Example:
echo. To sort a directory pipe the output of the dir
echo. command into %~n0 like this:
echo. dir /b^|%~n0
echo.
echo.Source: http://www.dostips.com
goto:EOF
)
if "%~1" NEQ "~" (
for /f "tokens=1,* delims=," %%a in ('"%~f0 ~ %*|sort"') do echo.%%b
goto:EOF
)
SETLOCAL ENABLEDELAYEDEXPANSION
set /a n=%~2+0
for /f "tokens=1,* delims=]" %%A in ('"find /n /v """') do (
set f=,%%B
(
set f0=!f:~0,%n%!
set f0=!f0:~1!
rem call call set f=,%%%%f:*%%f0%%=%%%%
set f=,!f:~%n%!
)
for /f "delims=1234567890" %%b in ("!f!") do (
set f1=%%b
set f1=!f1:~1!
call set f=0%%f:*%%b=%%
)
for /f "delims=abcdefghijklmnopqrstuwwxyzABCDEFGHIJKLMNOPQRSTUWWXYZ~`@#$*_-+=:;',.?/\ " %%b in ("!f!") do (
set f2=00000000000000000000%%b
set f2=!f2:~-20!
call set f=%%f:*%%b=%%
)
echo.!f1!!f2!!f!,%%B
rem echo.-!f0!*!f1!*!f2!*!f!*%%a>&2
)
此代码可以对文件名进行排序,其中包含一个数字(即video100.mov很好,video100video10.mov会破坏它)
我的问题是我认为添加对此帮助程序fn的调用将再次打破它,所以我将尝试将此包含在我的修改后的renamer.bat中。任何帮助表示赞赏。
答案 0 :(得分:4)
用于提取扩展名的批处理可能会重置本地环境。
但是,你不需要它。您可以使用~x
选项提取扩展名。与此相似......
:monotonicrename
set /a counter = 0
for %%a in (%1\*.*) do (
if exist %%~fa (
set /a counter += 1
echo ren %%~fa !counter!%%~xa
)
)
goto :eof
在计数器中包含前导零,以便目录正确排序,用三行替换以前的重命名命令
set zcounter=0000!counter!
set zcounter=!zcounter:~-4!
echo ren %%~fa !counter!%%~xa
因此,将所有部分组合在一起,在批处理文件中添加刚创建的monotonicrename函数,该函数可以更简单...
@echo off
setlocal enabledelayedexpansion
call :monotonicrename %1
goto :eof
:monotonicrename
set /a counter = 0
for %%a in (%1\*.*) do (
if exist %%~fa (
set /a counter += 1
set zcounter=0000!counter!
set zcounter=!zcounter:~-4!
echo ren %%~fa !zcounter!%%~xa
)
)
goto :eof
答案 1 :(得分:1)
我没有遇到延迟扩展的任何问题,一切对我来说都很好(当然,除了我没有exttostr.bat
帮助脚本这一事实。)
无论如何,关于你的脚本有几点可以改进:
您无需将DIR
的结果存储到文件中以便以后读取它。您可以直接在FOR
循环中阅读输出。
您不需要帮助程序批处理脚本。可以使用%%a
修饰符和循环变量~x
从%%~xa
中提取扩展名。您可以通过从命令提示符发出HELP FOR
来阅读有关修饰符的更多信息。
重命名器批处理文件的名称可以在脚本中引用为%0
。您可以应用~n
修饰符,只需使用不带扩展名的名称。 ~nx
的组合修饰符将为您提供扩展名。
因此,以下是解决上述问题的脚本的样子:
::a monotonic file renamer
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
IF [%1] == [] GOTO usage
::initialize
SET /A counter=0
SET type=
SET /A ender=%1
::read lines one by one
FOR /F "usebackq delims=" %%a IN (`DIR /B /ON`) DO (
REM make sure we do not rename any of the working files
IF NOT "%%~a"=="%~nx0" (
SET /A counter+=1
RENAME "%%~a" "!counter!%%~xa"
ECHO Renamed "%%~a" to "!counter!%%~xa"
)
REM exit when we have run enough
IF "!counter!"=="!ender!" GOTO :EOF
)
GOTO :EOF
:usage
ECHO Usage: %~n0 NUMFILES
关于您的次要问题,可以像这样轻松解决:
使用100000
之类的内容作为counter
的初始值。 (但是你喜欢使用多少0,但可能不超过9个。)同样的值也添加到ender
。
重命名文件时,而不是!counter!
使用删除第一个字符(1
)的表达式:!counter:~1!
(事实上,这不是关于删除,而是关于从偏移量1开始提取子字符串,使用HELP SET
命令了解更多信息。
以下是上述脚本的修改版本:
::a monotonic file renamer
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
IF [%1] == [] GOTO usage
::initialize
SET /A counter=1000
SET type=
SET /A ender=%1
SET /A ender+=counter
::read lines one by one
FOR /F "usebackq delims=" %%a IN (`DIR /B /ON`) DO (
REM make sure we do not rename any of the working files
IF NOT "%%~a"=="%~nx0" (
SET /A counter+=1
RENAME "%%~a" "!counter:~1!%%~xa"
ECHO Renamed "%%~a" to "!counter:~1!%%~xa"
)
REM exit when we have run enough
IF "!counter!"=="!ender!" GOTO :EOF
)
GOTO :EOF
:usage
ECHO Usage: renamer NUMFILES
您还可以看到我做了一些其他增强功能,例如确保文件名用双引号括起来,并使用GOTO :EOF
代替GOTO exit
(:EOF
是一个特殊的增强功能 - 指向批处理脚本末尾的定义标签,因此您无需定义自己的标签。