Comment la commande Windows RENAME (REN) interprète-t-elle les caractères génériques?
La fonction d'aide intégrée n'est d'aucune aide - elle ne traite pas du tout les caractères génériques.
L’ aide en ligne de Microsoft technet XP n’est pas meilleure. Voici tout ce qu'il a à dire à propos des jokers:
"Vous pouvez utiliser des caractères génériques (
*
et?
) dans l'un ou l'autre des paramètres de nom de fichier. Si vous utilisez des caractères génériques dans nomfichier2, les caractères représentés par les caractères génériques seront identiques aux caractères correspondants dans nomfichier1."
Pas beaucoup d’aide - cette déclaration peut être interprétée de nombreuses manières.
J'ai parfois réussi à utiliser des caractères génériques dans le paramètre filename2 , mais cela a toujours été un essai et une erreur. Je n'ai pas été en mesure d'anticiper ce qui fonctionne et ce qui ne fonctionne pas. Souvent, j'ai dû écrire un petit script batch avec une boucle FOR qui analyse chaque nom afin de pouvoir créer chaque nouveau nom selon les besoins. Pas très pratique.
Si je connaissais les règles de traitement des caractères génériques, je pensais pouvoir utiliser la commande RENAME de manière plus efficace sans avoir à recourir au traitement par lots aussi souvent. Bien sûr, connaître les règles profiterait également au développement par lots.
(Oui, c’est un cas dans lequel je poste une question et une réponse jumelées. Je suis fatigué de ne pas connaître les règles et j’ai décidé d’expérimenter moi-même. J’imagine que beaucoup d’autres pourraient être intéressés par ce que j’ai découvert.)
la source
*
Windows. Cela a d'énormes conséquences. J'aurais aimé connaître ce site cependant; cela aurait peut-être facilité mon enquête. Les règles MSDOS7 diffèrent considérablement des anciennes règles DOS avant les noms de fichier longs et constituent un pas en avant dans la façon dont Windows les gère. J'avais trouvé les règles DOS pré-nom de fichier pré-longues, et elles ne valaient rien à mon enquête.Réponses:
Ces règles ont été découvertes après de nombreux tests sur une machine Vista. Aucun test n'a été effectué avec Unicode dans les noms de fichiers.
RENAME nécessite 2 paramètres - un masque source, suivi d'un masque cible. SourceMask et targetMask peuvent contenir
*
et / ou des?
caractères génériques. Le comportement des caractères génériques change légèrement entre les masques source et cible.Remarque - REN peut être utilisé pour renommer un dossier, mais les caractères génériques ne sont autorisés ni dans le masque source, ni dans le masque cible lors de l'attribution d'un nouveau nom à un dossier. Si le masque source correspond à au moins un fichier, le ou les fichiers seront renommés et les dossiers seront ignorés. Si le masque de source ne correspond qu'à des dossiers et pas à des fichiers, une erreur de syntaxe est générée si des caractères génériques apparaissent dans la source ou la cible. Si le masque source ne correspond à rien, le résultat est une erreur "fichier non trouvé".
De plus, lorsque vous renommez des fichiers, les caractères génériques ne sont autorisés que dans la partie nom de fichier du masque de source. Les caractères génériques ne sont pas autorisés dans le chemin menant au nom du fichier.
masque de source
SourceMask fonctionne comme un filtre pour déterminer quels fichiers sont renommés. Les caractères génériques fonctionnent ici de la même manière que toute autre commande filtrant les noms de fichiers.
?
- Correspond à n'importe quel caractère 0 ou 1 sauf.
Ce caractère générique est gourmand - il consomme toujours le caractère suivant s'il ne s'agit pas d'un.
caractère..
*
- Correspond à tout caractère ou plus, y compris.
(avec une exception ci-dessous). Ce joker n'est pas gourmand. La correspondance sera aussi faible ou aussi grande que nécessaire pour permettre la correspondance des caractères suivants.Tous les caractères non génériques doivent correspondre, à quelques exceptions près.
.
- Correspond elle-même ou peut correspondre à la fin du nom (rien) s'il ne reste plus de caractères. (Remarque - un nom Windows valide ne peut pas se terminer par.
){space}
- Correspond elle-même ou peut correspondre à la fin du nom (rien) s'il ne reste plus de caractères. (Remarque - un nom Windows valide ne peut pas se terminer par{space}
)*.
à la fin - Correspond à tous les caractères 0 ou plus, à l' exception de.
La terminaison.
peut en réalité être une combinaison de.
et{space}
aussi longtemps que le tout dernier caractère du masque est.
Ceci est la seule et unique exception où*
ne correspond simplement à aucun ensemble de caractères.Les règles ci-dessus ne sont pas si complexes. Mais il existe une autre règle très importante qui rend la situation confuse: le masque source est comparé à la fois au nom long et au nom court 8.3 (s'il existe). Cette dernière règle peut rendre l'interprétation des résultats très délicate, car ce n'est pas toujours évident lorsque le masque correspond via le nom abrégé.
Il est possible d’utiliser RegEdit pour désactiver la génération de noms courts 8.3 sur des volumes NTFS, l’interprétation des résultats du masque de fichier étant alors beaucoup plus simple. Tous les noms abrégés générés avant la désactivation des noms abrégés resteront.
targetMask
Remarque - Je n'ai effectué aucun test rigoureux, mais il semble que ces mêmes règles fonctionnent également pour le nom cible de la commande COPY.
TargetMask spécifie le nouveau nom. Il est toujours appliqué au nom complet complet. Le masque cible n'est jamais appliqué au nom abrégé 8.3, même si le masque source correspond au nom abrégé 8.3.
La présence ou l'absence de caractères génériques dans le masque source n'a aucun impact sur la façon dont les caractères génériques sont traités dans le masque cible.
Dans la discussion suivante -
c
représente un caractère qui n'est pas*
,?
ou.
Le targetMask est traité par rapport au nom de source strictement de gauche à droite sans suivi en arrière.
c
- Avance la position dans le nom de la source tant que le caractère suivant n'est pas.
et ajoutec
au nom de la cible. (Remplace le caractère qui était dans la source avecc
, mais ne remplace jamais.
)?
- Correspond au caractère suivant du nom long de la source et l'ajoute au nom de la cible tant que le caractère suivant ne l'est pas.
Si le caractère suivant est.
ou si à la fin du nom de la source, aucun caractère n'est ajouté au résultat et au résultat actuel. la position dans le nom de la source est inchangée.*
à la fin de targetMask - Ajoute tous les caractères restants de la source à la cible. Si déjà à la fin de la source, alors ne fait rien.*c
- Correspond à tous les caractères source de la position actuelle jusqu'à la dernièrec
occurrence de (correspondance gloutonne sensible à la casse) et ajoute le jeu de caractères correspondant au nom de la cible. Sic
est introuvable, tous les caractères restants de la source sont ajoutés, suivis de.c
C’est la seule situation que je connaisse dans laquelle la correspondance de modèle de fichier Windows est sensible à la casse.*.
- Correspond à tous les caractères source de la position actuelle jusqu'à la dernière occurrence de.
(correspondance gloutonne) et ajoute le jeu de caractères correspondant au nom de la cible. Si.
est introuvable, tous les caractères restants de la source sont ajoutés, suivis de.
*?
- Ajoute tous les caractères restants de la source à la cible. Si déjà à la fin de la source alors ne fait rien..
without*
in front - Avance la position dans la source de la première occurrence de.
sans copier aucun caractère et l'ajoute.
au nom de la cible. Si.
n'est pas trouvé dans la source, passe à la fin de la source et est ajouté.
au nom de la cible.Après l'targetMask a été épuisé, toute fuite
.
et{space}
sont rogné la fin du nom cible résultant parce que les noms de fichiers Windows ne peut pas finir avec.
ou{space}
Quelques exemples pratiques
Remplacez un personnage aux 1ère et 3ème positions avant toute extension (ajoute un 2ème ou 3ème caractère s'il n'existe pas encore)
Changer l'extension (finale) de chaque fichier
Ajouter une extension à chaque fichier
Supprimer toute extension supplémentaire après l'extension initiale. Notez qu’il
?
faut utiliser adéquat pour conserver le nom complet et l’extension initiale existants.Comme ci-dessus, mais filtrez les fichiers dont le nom initial et / ou l'extension est supérieur à 5 caractères afin qu'ils ne soient pas tronqués. (Évidemment, on pourrait en ajouter un
?
à chaque extrémité du targetMask pour conserver les noms et les extensions jusqu'à 6 caractères)Changer les caractères après le dernier
_
nom et tenter de conserver l’extension. (Ne fonctionne pas correctement si_
apparaît en extension)Tout nom peut être divisé en composants délimités par des
.
caractères. Vous ne pouvez les ajouter ou les supprimer qu'à la fin de chaque composant. Les caractères ne peuvent pas être supprimés ou ajoutés au début ou au milieu d'un composant tout en préservant le reste avec des caractères génériques. Les substitutions sont autorisées n'importe où.Si les noms abrégés sont activés, un masque source comportant au moins 8
?
pour le nom et au moins 3?
pour l'extension correspondra à tous les fichiers car il correspondra toujours au nom abrégé 8.3.Bizarre / bug utile? pour supprimer les préfixes de nom
Cet article de SuperUser décrit comment utiliser un ensemble de barres obliques (
/
) pour supprimer les caractères de tête d'un nom de fichier. Une barre oblique est requise pour chaque caractère à supprimer. J'ai confirmé le comportement sur une machine Windows 10.Cette technique ne fonctionne que si les masques source et cible sont placés entre guillemets. Tous les formulaires suivants sans les guillemets requis échouent avec cette erreur:
The syntax of the command is incorrect
Le
/
ne peut pas être utilisé pour supprimer des caractères au milieu ou à la fin d'un nom de fichier. Il ne peut supprimer que les caractères de préfixe.Techniquement, cela
/
ne fonctionne pas comme un joker. Au lieu de cela, il effectue une simple substitution de caractère, mais après la substitution, la commande REN reconnaît que ce/
n'est pas valide dans un nom de fichier et supprime les/
barres obliques du nom. REN donne une erreur de syntaxe s'il détecte/
au milieu d'un nom de cible.RENAME possible bug - une seule commande peut renommer le même fichier deux fois!
Commencer dans un dossier de test vide:
Je crois que le masque source
*1*
correspond d’abord au nom de fichier long, et le fichier est renommé avec le résultat attendu de223456789.123.x
. RENAME continue ensuite à rechercher plus de fichiers à traiter et trouve le fichier nouvellement nommé via le nouveau nom abrégé de223456~1.X
. Le fichier est ensuite renommé, donnant le résultat final de223456789.123.xx
.Si je désactive la génération de noms 8.3, le RENAME donne le résultat attendu.
Je n'ai pas complètement défini toutes les conditions de déclenchement qui doivent exister pour induire ce comportement étrange. Je craignais qu'il ne soit possible de créer un RENAME récursif sans fin, mais je n'ai jamais réussi à le provoquer.
Je crois que tout ce qui suit doit être vrai pour induire le bogue. Tous les incidents que j'ai vus comportaient les conditions suivantes, mais tous les incidents répondant aux conditions suivantes ne l'ont pas été.
la source
REN /?
.Copy of
préfixe en utilisant une technique obscure de barre oblique:ren "Copy of *.txt" "////////*"
Semblable à exebook, voici une implémentation en C # pour obtenir le nom de fichier cible à partir d’un fichier source.
J'ai trouvé une petite erreur dans les exemples de dbenham:
Voici le code:
Et voici une méthode de test NUnit pour tester les exemples:
la source
J'ai réussi à écrire ce code en BASIC pour masquer les noms de fichiers génériques:
la source
Peut-être que quelqu'un peut trouver cela utile. Ce code JavaScript est basé sur la réponse de dbenham ci-dessus.
Je n'ai pas
sourceMask
beaucoup testé , maistargetMask
correspond à tous les exemples donnés par dbenham.la source