2011-06-29 141 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是一個特殊的預定義標籤,指向批處理腳本的末尾,因此您不需要定義自己的標籤)。