@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
Eh bien, pas trop difficile après tout.
Je ne suis pas tout à fait d'accord avec votre spécification - je ne supprime pas les fichiers, donc je n'ai simplement pas renommé les cibles avec des noms dupliqués.
On accorde beaucoup trop d'attention à essayer de traiter des noms de fichiers stupides. Si vous utilisez des caractères comme !%^)=
dans vos noms de fichiers - et bien - vous êtes si intelligent - vous avez compris.
Donc, en supposant que les caractères et les espaces des noms de fichiers sont raisonnables, cela fonctionne !
Configurez d'abord votre relative root
(sous-répertoire de départ), les masques de fichiers à utiliser, anciens et nouveaux, et l'extension. J'ai utilisé le set "var=string"
syntaxe pour éviter l'application d'espaces terminaux parasites qui sont invisibles et peuvent provoquer le chaos. Notez également que dans une affectation de chaîne de caractères, les espaces des deux côtés de '=' sont significatifs.
La première étape est telle que documentée. Je ne suis pas sûr de ce qu'il faut faire s'il y a déjà des fichiers correspondant au nouveau nom dans l'arbre - alors je ne fais rien. Je compte les lignes qui apparaissent à partir d'un fichier dir /s/b/a-d
(répertoire, avec sous-répertoires, forme de base (donc pas d'en-tête) et pas de nom de répertoire) devrait être d'environ 0 si tout va bien.
J'aime configurer les tempfiles en utilisant la méthode showm. S'il n'y a pas de noms dans %temp%
correspondant au nom aléatoire choisi, alors il devrait être sûr d'utiliser ce nom + n'importe quelle annexe que vous souhaitez (afin de pouvoir créer plusieurs tempfiles, si nécessaire).
L'étape suivante consiste à récupérer le sous-répertoire des fichiers de l'ancien nom sous une forme basique, mais cette fois dans un fichier temporaire. Ce qui est sorti est une ligne pour chaque fichier, structurée comme la partie NOM seulement ( %%~ni
) un astérisque et le nom complet du fichier ( %%~fi
). L'astérisque agit comme un délimiteur de colonne et est sûr parce que *
ne peut pas apparaître dans un nom de fichier.
Vient ensuite la phase de renommage. Nous commençons le COUNT
à 1000 afin que nous puissions utiliser les 3 derniers caractères pour créer le nom. Si vous voulez commencer à 001, utilisez plutôt 1001. PREV
est initialisé à une valeur qui ne peut pas apparaître comme un nom de fichier à renommer.
De nouveau, comptez les noms à renommer. S'il y en a trop, abandonnez le navire.
L'étape suivante consiste à trier le fichier temporaire, afin que le résultat soit traité dans l'ordre du nom du fichier de base original (avant le "*" dans chaque ligne) et ensuite, si le nom correspond, dans l'ordre alphabétique du nom du sous-répertoire (puisque nom*parent sera trié avant nom*parent). \subdir ). Chaque NOM rencontré est ensuite transmis à la fonction :incren
routine - cité pour tenir compte de l'exigence des espaces dans les noms de fichier.
La première chose que fait la routine INCREN est de vérifier si le nom répète le nom précédent rencontré. Si c'est le cas, le nom est ignoré (car il a déjà été traité). PREV
est alors fixé au prochain nom rencontré. SET "prev=%~1"
supprime les guillemets du premier paramètre, puis attribue le résultat à prev
et les guillemets empêchent les espaces parasites de s'intercaler. firstname
y secondname
sont alors fixés à [rien].
Ensuite, nous analysons à nouveau le fichier temporaire, en recherchant un nom correspondant comme premier jeton et en assignant le deuxième jeton (le nom complet du fichier) à la fonction %%n
lorsque le premier est trouvé, le prénom n'est pas défini, il faut donc le définir comme le nom complet du fichier. Si un second nom est trouvé, alors firstname
sera déjà défini, alors définissez SKIPPED
pour signaler qu'un problème a été rencontré. Si le deuxième nom de fichier n'a pas encore été défini, alors l'option secondname
a que nom du fichier complet Si d'autres correspondances sont trouvées, alors comme secondname
est maintenant défini, rien d'autre ne sera fait.
Après avoir traité le dossier, nous aurons firstname
fixé au premier nom de fichier complet (puisque le relative-Root est le premier rencontré) et secondname
ne sera défini que si 2 noms correspondants ou plus ont été trouvés. Dans ce cas, l'option firstname
à la valeur du deuxième nom rencontré, qui sera dans un sous-répertoire inférieur.
Maintenant, faites le RENAME. J'ai juste ECHO
mais pour l'activer, il faut retirer le ECHO
de la ECHO REN...
ligne. Nous savons firstname
contient le nom complet du fichier à renommer, et nous savons que la structure du nouveau nom de fichier sera le nouveau masque + les 3 derniers caractères de COUNT
+un point+l'extension sélectionnée.
et remettre le compte à zéro pour le prochain renommage...
Voici un essai avec le ECHO
retiré :
============= 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
Notez que ceci a été exécuté sur un lecteur FAT, donc la séquence des fichiers réels est la même dans les deux listings.