@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
まあ、結局のところ、それほど難しいことではありません。
あなたの仕様に完全に沿っていません-私はファイルの削除を避けているので、名前が重複しているターゲットの名前を変更しませんでした。
ばかげたファイル名 IMO を処理しようとすることにあまりにも多くの注意が払われています。ファイル名に のような文字を使用している場合!%^)=
、まあ - あなたはとても頭がいいので、それを理解します。
したがって、適切なファイル名文字とスペースを想定して、動作します!
最初に、relative root
(開始サブディレクトリ) 名、使用するファイルマスク、古いものと新しいもの、および拡張子を設定します。私はこのset "var=string"
構文を使用して、目に見えず、混乱を引き起こす可能性のある浮遊端末スペースの適用を回避しました。また、文字列の代入では、「=」の両側のスペースが重要であることに注意してください。
最初のステップは文書化されているとおりです。新しい名前に一致するファイルがすでにツリーにある場合はどうすればよいかわかりません。何もしないでください。(ディレクトリ、サブディレクトリあり、基本形式 (ヘッダーなし)、ディレクトリ名なし)から表示される行をカウントするdir /s/b/a-d
と、すべてが順調であれば、約 0 になるはずです。
メソッド showm を使用して一時ファイルを設定するのが好きです。選択したランダムな名前に一致する名前がない場合は、%temp%
その名前と任意の付録を使用しても安全です (したがって、必要に応じて多くの一時ファイルを作成できます)。
次のステップは、古い名前のファイルのサブディレクトリを基本形式で再度取得することですが、今回は一時ファイルに出力します。出力されるのは、各ファイルの行で、NAME 部分のみ ( %%~ni
) アスタリスクと完全なファイル名 ( %%~fi
) で構成されています。*
アスタリスクは列区切り記号として機能し、ファイル名には使用できないため安全です。
次は名前変更フェーズです。COUNT
最後の 3 文字を使用して名前を作成できるように、 を 1000 から開始します。001 から開始したい場合は、代わりに 1001 を使用してください。PREV
名前を変更するファイル名として表示できない値に初期化されます。
ここでも、名前を変更する名前を数えます。多すぎる場合は、船を放棄してください。
次のステップは一時ファイルをソートすることです。結果は元のベースファイル名 (各行の「*」の前) の順序で処理され、名前が一致する場合はサブディレクトリ名のアルファベット順 (name* から) で処理されます。親は name*parent\subdir の前にソートされます)。次に、検出された各 NAME がルーチンに渡され:incren
ます - ファイル名のスペース要件に対応するために引用符が付けられます。
INCREN ルーチンが最初に行うことは、名前が以前に検出された名前を繰り返すかどうかを確認することです。存在する場合、その名前は無視されます (既に処理されているため)。PREV
次に見つかった名前に設定されます。SET "prev=%~1"
最初のパラメーターから引用符を削除し、結果をに割り当て、引用符を囲んで、迷子のスペースが突き当たるのをprev
防ぎます。その後、[nothing] に設定されます。firstname
secondname
次に、一時ファイルを再度スキャンし、一致する名前を最初のトークンとして探し、2 番目のトークン (完全なファイル名) を%%n
最初のファイル名が見つかった場合、firstname は設定されていないため、完全なファイル名に設定します。2 番目の名前が見つかった場合は、firstname
既に設定されSKIPPED
ているため、問題が発生したことを示すフラグを設定します。2 番目のファイル名がまだ設定されていない場合は、そのフル ファイル名に設定secondname
します。secondname
ファイルを処理した後firstname
、最初の完全なファイル名に設定され (相対ルートが最初に検出されるため)、 secondname
2 つ以上の一致する名前が見つかった場合にのみ設定されます。その場合、firstname
2 番目に見つかった名前の値に設定します。これは、下位のサブディレクトリになります。
RENAMEを実行します。編集したばかりですが、アクティブにするには、行からECHO
を削除します。名前を変更するファイルの完全な名前が含まれていることがわかり、新しいファイル名の構造が新しいマスク +ドットの最後の 3 文字 + 選択した拡張子になることがわかっています。ECHO
ECHO REN...
firstname
COUNT
次の名前変更に備えてカウントを増やします...
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
これは FAT ドライブに対して実行されたので、実際のファイルのシーケンスは 2 つのリストで同じであることに注意してください。