@ECHO OFF
SETLOCAL
SET "relroot=u:\photos collection 01"
SET "oldmask=im age"
SET "newmask=new name"
SET "ext=jpg"
SET "skipped="
::
:: step 1 - ensure no 'newname*.ext' exists in the subtree
::
FOR /f %%i IN (
'DIR /s/b/a-d "%relroot%\%newmask%*.%ext%" 2^>nul^|FIND /c /v "" '
) DO IF NOT %%i==0 ECHO Files matching new mask already exist&GOTO :EOF
::
:: step 2 - list target files
::
:temploop
SET tempfile=%temp%\Photo%random%
IF EXIST "%tempfile%*" GOTO temploop
:: now have random tempfile name
(
FOR /f "delims=" %%i IN (
'DIR /s/b/a-d "%relroot%\%oldmask%*.%ext%" '
) DO (
ECHO %%~ni*%%~fi
)
)>"%tempfile%1"
::
:: Now do the rename
::
SET count=1000
SET prev=%newmask%
FOR /f %%i IN ('find /c "*" ^<"%tempfile%1"') DO IF %%i gtr 1000 ECHO %%i files - exceeds capacity&GOTO :eof
FOR /f "delims=*" %%i IN ('SORT "%tempfile%1"') DO (CALL :incren "%%i")
IF DEFINED skipped ECHO some files were NOT renamed&DIR /s/b/a-d "%relroot%\%oldmask%*.%ext%"
DEL "%tempfile%1"
GOTO :eof
:incren
:: repeat?
IF "%prev%"==%1 GOTO :EOF
:: no - process next name found
SET "prev=%~1"
FOR %%n IN (firstname secondname) DO (SET %%n=)
:: scan the tempfile, looking for matches to name found
FOR /f "usebackqtokens=1,2delims=*" %%m IN ("%tempfile%1") DO IF /i "%%m"=="%prev%" (
IF DEFINED firstname SET skipped=Y&IF NOT DEFINED secondname SET secondname=%%n
IF NOT DEFINED firstname SET firstname=%%n
)
IF DEFINED secondname SET firstname=%secondname%
ECHO REN "%firstname%" "%newmask%%count:~-3%.%ext%"
SET /a count+=1
GOTO :eof
好吧,畢竟不是太難。
不太符合你的規範 - 我不想刪除文件,所以我mereley沒有重命名重名的任何目標。
試圖處理愚蠢的文件名海事組織過於關注。如果你在你的文件名中使用了!%^)=
這樣的字符 - 那麼你非常聰明 - 你會發現它。
因此,假設合理的文件名字符和空格,工作!
首先設置您的relative root
(起始子目錄)名稱,要使用的文件掩碼,舊的和新的以及擴展名。我使用set "var=string"
語法來避免應用雜亂的終端空間,這些空間是不可見的並且可能導致混亂。還要注意,在一個字符串賦值中,'='兩邊的空格是重要的。
第一步是記錄。如果在樹中已經有與新名稱匹配的文件,不知道該怎麼做 - 所以不要做任何事情。從dir /s/b/a-d
(包含子目錄,基本表單(因此不包含標題)和目錄名稱)目錄中出現的行數應該爲0,如果一切正常。
我喜歡用showm方法設置tempfiles。如果%temp%
中沒有與選擇的隨機名匹配的名稱,那麼使用該名稱+您喜歡的任何附錄應該是安全的(如果需要,可以創建許多臨時文件)。
下一步是獲取子目錄再次使用基本形式的舊名稱文件 - 但是這次輸出到tempfile。什麼是輸出是每個文件的一行,只有名稱部分(%%~ni
)以星號和完整文件名(%%~fi
)結構。星號充當列分隔符並且安全,因爲*
不能出現在文件名中。
接下來是重命名階段。我們在1000處開始COUNT
,以便我們可以使用最後3個字符來創建名稱。你想從001開始,只需要使用1001。 PREV
被初始化爲一個不能顯示爲要重命名的文件名的值。
再次,計算要重命名的名稱。如果太多,放棄船舶。
下一步是對tempfile進行排序,因此結果將按照原始base-filename(在每行中的「*」之前)進行處理,然後如果名稱匹配,按照子目錄名稱的字母順序(因爲name * parent會在name * parent \ subdir之前排序)。遇到的每個名稱然後傳遞到:incren
例程 - 引用以適應文件名空間要求。
INCREN例程所做的第一件事是檢查名稱是否重複遇到的以前的名稱。如果是這樣,名稱將被忽略(因爲它已經被處理)。然後將PREV
設置爲遇到的下一個名稱。 SET "prev=%~1"
去除第一個參數報價,那麼結果firstname
分配給prev
和封閉引號防止雜散空間從碰撞。和secondname
,然後設置爲[無]
然後,我們再次掃描臨時文件,找了匹配名稱作爲第一個標記並將第二個標記(全文件名)分配給%%n
當第一個找到時,firstname沒有設置,因此將其設置爲完整文件名。 如果找到第二個名字,則firstname
將已設置,因此請設置SKIPPED
來標記已遇到問題。如果第二個文件名尚未設置,則將secondname
設置爲即全文件名 應該進一步匹配找到,那麼因爲現在設置了secondname
,所以不會做任何進一步的處理。
處理完文件後,我們將firstname
設置爲第一個完整文件名(因爲相對根是第一個遇到的),並且secondname
僅在找到兩個或更多匹配名稱時纔會設置。在這種情況下,將firstname
設置爲遇到的第二個名稱的值,該名稱將位於較低的子目錄中。
現在做RENAME。我只是ECHO
編輯它,但要激活,從ECHO REN...
線刪除ECHO
。我們知道firstname
包含要重命名的文件的全名,並且我們知道新文件名的結構將成爲新的掩碼+ COUNT
的最後3個字符+一個點+所選擴展名。
並撞上計數準備下一次重命名...
這是一個測試運行與ECHO
刪除:
============= before =========
u:\photos collection 01\im age 612.jpg
u:\photos collection 01\im age 003.jpg
u:\photos collection 01\im age 005.jpg
u:\photos collection 01\im age 610.jpg
u:\photos collection 01\im age 009.jpg
u:\photos collection 01\im age 609.jpg
u:\photos collection 01\im age 505.jpg
u:\photos collection 01\selection 01\im age 001.jpg
u:\photos collection 01\selection 01\im age 004.jpg
u:\photos collection 01\selection 01\im age 005.jpg
u:\photos collection 01\selection 01\im age 006.jpg
============= run =========
some files were NOT renamed
u:\photos collection 01\im age 005.jpg
============= after =========
u:\photos collection 01\new name009.jpg
u:\photos collection 01\new name001.jpg
u:\photos collection 01\im age 005.jpg
u:\photos collection 01\new name008.jpg
u:\photos collection 01\new name005.jpg
u:\photos collection 01\new name007.jpg
u:\photos collection 01\new name006.jpg
u:\photos collection 01\selection 01\new name000.jpg
u:\photos collection 01\selection 01\new name002.jpg
u:\photos collection 01\selection 01\new name003.jpg
u:\photos collection 01\selection 01\new name004.jpg
注意這是agains FAT驅動器執行,因此實際文件的順序是兩個清單相同。
我不相信,有任何理智的方法來實現4)使用批處理文件。爲此你需要一些真正的編程語言。如果您想保持接近腳本,請考慮PowerShell或VBScript/JScript。 –