2011-06-29 146 views
2

我正在写一个批处理脚本单调文件重命名。基本上,它使所有文件的标题1 2 3 4 ....等等。我已经扩展它能够处理不同类型的文件(txt,doc,flv等),但并不是所有的东西都在运行。与enabledelayedexpansion问题文件重命名批处理脚本

我的主要担忧是我打破了之前制作的延迟扩展呼叫。现在使用!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” 我还没有找到解决方法,但只是它确实是目标的预期结果分类。我唯一的解决方法是在前面填充足够的零。

在此先感谢您的任何见解!


万事俱备,但第二个问题。我想我说得不好。我有这个问题,当我在目录文件名,而不是写出时。所以他们已经需要填充。我希望有一些其他的方式来读取目录,并对其进行适当的排序。

最有前途的事情,我发现在这里: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

由于'exttostr'是一个批处理文件,你需要一个'call'来调用它,否则你的脚本会停在那里。 – jeb

+0

谢谢,“电话”确实有效。如果任何人都可以帮助我添加代码,那将是完美的。那么我只需要一个文件! :-)谢谢你的帮助,以及那些已经帮助过我的人。 – walrus

回答

3

可能是提取扩展的批处理重置了本地环境。

但是,你并不需要它。您可以使用~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 
+0

您已经放弃了原始功能的一部分,这是关于限制重新编号的数量(脚本的第一个参数)。另一方面,像我一样,使用'IN(*。*)'而不是'IN(\'DIR \')'是个好主意。 –

+0

我的目标并不是提供OPs案例的完整解决方案,只是为了展示如何解决使用具有前导零的计数器重命名并留下扩展名的OP问题。 –

1

我没有延迟的扩张遇到任何问题,一切正常,我(除,当然,对于这个事实,我没有足够的exttostr.bat助手脚本。)

无论如何,有几件事情,可能你的脚本进行改进:

  1. 你并不需要的DIR结果保存到一个文件然后需要读取它。您可以直接在FOR循环中读取输出。

  2. 您不需要帮助器批处理脚本。可以使用~x修饰符和循环变量%%~xa%%a中提取扩展名。您可以通过从命令提示符发出HELP FOR来阅读有关修饰符的更多信息。

  3. 重命名批处理文件自己的名称可以在脚本中被引用为%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 

至于你的次要问题,它都可以轻松解决这样的:

  1. 使用像100000这样的counter的初始值。 (尽管使用了许多0,但可能不超过9个)。将相同的值也添加到ender

  2. 在重命名文件,而不是!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是一个特殊的预定义标签,指向批处理脚本的末尾,因此您不需要定义自己的标签)。