Diese Regeln wurden nach umfangreichen Tests auf einem Vista-Rechner entdeckt. Es wurden keine Tests mit Unicode in Dateinamen durchgeführt._
RENAME erfordert 2 Parameter - eine sourceMask, gefolgt von einer targetMask. Sowohl die sourceMask als auch die targetMask können *
und/oder ?
Wildcards enthalten. Das Verhalten der Platzhalter ändert sich leicht zwischen Quell- und Zielmaske.
Note - REN kann zum Umbenennen eines Ordners verwendet werden, aber Platzhalter sind nicht in der sourceMask oder targetMask beim Umbenennen eines Ordners erlaubt. Wenn die sourceMask auf mindestens eine Datei zutrifft, wird die Datei bzw. werden die Dateien umbenannt und die Ordner werden ignoriert. Wenn die sourceMask nur mit Ordnern und nicht mit Dateien übereinstimmt, wird ein Syntaxfehler erzeugt, wenn Platzhalter in source oder target vorkommen. Wenn die sourceMask auf nichts zutrifft, wird eine Fehlermeldung “Datei nicht gefunden” ausgegeben.
Auch beim Umbenennen von Dateien sind Platzhalter nur im Dateinamensteil der sourceMask erlaubt. Platzhalter sind im Pfad, der zum Dateinamen führt, nicht erlaubt.
sourceMask
Die sourceMask dient als Filter, um zu bestimmen, welche Dateien umbenannt werden. Die Platzhalter funktionieren hier genauso wie bei jedem anderen Befehl, der Dateinamen filtert.
?
- Passt auf jedes 0- oder 1-Zeichen außer .
Dieser Platzhalter ist gierig - er verbraucht immer das nächste Zeichen, wenn es kein .
ist. Er passt jedoch nicht, wenn er am Namensende steht oder wenn das nächste Zeichen ein .
ist
*
- Passt auf jedes 0- oder mehr-Zeichen einschließlich .
(mit einer Ausnahme unten). Dieser Platzhalter ist nicht gierig. Er passt so wenig oder so viel, wie nötig ist, damit nachfolgende Zeichen passen.
Alle Nicht-Wildcard-Zeichen müssen selbst übereinstimmen, mit ein paar Ausnahmen für Sonderfälle.
.
- Stimmt mit sich selbst überein oder kann mit dem Ende des Namens (nichts) übereinstimmen, wenn keine weiteren Zeichen übrig bleiben. (Hinweis - ein gültiger Windows-Name kann nicht mit .
enden)
{space}
- Passt auf sich selbst oder auf das Ende des Namens (nichts), wenn keine weiteren Zeichen übrig bleiben. (Hinweis - ein gültiger Windows-Name kann nicht mit {space}
enden)
*.
am Ende - Passt auf 0 oder mehr Zeichen außer .
Das abschließende .
kann tatsächlich eine beliebige Kombination aus .
und {space}
sein, solange das allerletzte Zeichen in der Maske .
ist Dies ist die einzige Ausnahme, bei der *
nicht einfach auf eine beliebige Menge von Zeichen passt.
Die obigen Regeln sind nicht sehr komplex. Aber es gibt eine weitere sehr wichtige Regel, die die Situation verwirrend macht: Die sourceMask wird sowohl mit dem langen Namen als auch mit dem kurzen 8.3-Namen (falls vorhanden) verglichen. Diese letzte Regel kann die Interpretation der Ergebnisse sehr knifflig machen, weil es nicht immer offensichtlich ist, wenn die Maske über den kurzen Namen abgeglichen wird.
Es ist möglich, mit RegEdit die Generierung von 8.3-Kurznamen auf NTFS-Datenträgern zu deaktivieren, wodurch die Interpretation der Ergebnisse der Dateimaske viel einfacher wird. Alle kurzen Namen, die vor der Deaktivierung der kurzen Namen generiert wurden, bleiben erhalten.
targetMask
Hinweis - Ich habe keine strengen Tests durchgeführt, aber es scheint, dass die gleichen Regeln auch für den Zielnamen des COPY-Befehls gelten
Die targetMask gibt den neuen Namen an. Sie wird immer auf den vollen langen Namen angewendet; die targetMask wird nie auf den kurzen 8.3-Namen angewendet, selbst wenn die sourceMask mit dem kurzen 8.3-Namen übereinstimmte.
Das Vorhandensein oder Fehlen von Platzhaltern in der sourceMask hat keinen Einfluss darauf, wie Platzhalter in der targetMask verarbeitet werden.
In der folgenden Diskussion - c
steht für jedes Zeichen, das nicht *
, ?
oder .
ist
Die targetMask wird streng von links nach rechts gegen den Quellnamen verarbeitet, ohne Rückverfolgung.
c
- Verschiebt die Position innerhalb des Quellnamens nur, wenn das Quellzeichen nicht .
ist, und hängt immer c
an den Zielnamen an. (Ersetzt das Zeichen, das in der Quelle war, durch c
, aber ersetzt niemals .
)
?
- Passt das nächste Zeichen aus dem langen Quellnamen an und hängt es an den Zielnamen an, solange das Quellzeichen nicht .
ist. Wenn das nächste Zeichen .
ist oder am Ende des Quellnamens steht, wird kein Zeichen zum Ergebnis hinzugefügt und die aktuelle Position innerhalb des Quellnamens bleibt unverändert.
*
am Ende von targetMask - Hängt alle verbleibenden Zeichen aus der Quelle an das Ziel an. Wenn bereits am Ende der Quelle, dann macht es nichts.
*c
- Passt auf alle Zeichen der Quelle ab der aktuellen Position bis zum letzten Vorkommen von c
(Groß-/Kleinschreibung wird beachtet) und fügt die übereinstimmende Zeichengruppe an den Zielnamen an. Wenn c
nicht gefunden wird, werden alle verbleibenden Zeichen aus der Quelle angehängt, gefolgt von c
Dies ist die einzige mir bekannte Situation, in der die Groß- und Kleinschreibung bei der Mustererkennung von Windows-Dateien berücksichtigt wird.
*.
- Passt auf alle Quellzeichen ab der aktuellen Position bis zum letzten Vorkommen von .
(gierige Übereinstimmung) und fügt die übereinstimmende Menge von Zeichen an den Zielnamen an. Wenn .
nicht gefunden wird, dann werden alle verbleibenden Zeichen aus der Quelle angehängt, gefolgt von .
*?
- Hängt alle verbleibenden Zeichen aus der Quelle an das Ziel an. Wenn bereits am Ende der Quelle, dann geschieht nichts.
.
ohne *
davor - Geht die Position in der Quelle bis zum ersten Vorkommen von .
vor, ohne irgendwelche Zeichen zu kopieren, und hängt .
an den Zielnamen an. Wenn .
in der Quelle nicht gefunden wird, dann wird bis zum Ende der Quelle weitergeschaltet und .
an den Zielnamen angehängt.
Nachdem die targetMask ausgeschöpft wurde, werden alle nachfolgenden .
und {space}
vom Ende des resultierenden Zielnamens abgeschnitten, da Windows-Dateinamen nicht mit .
oder {space}
enden können
Einige praktische Beispiele
Ersetzen eines Zeichens an der ersten und dritten Position vor einer Erweiterung (fügt ein 2. oder 3. Zeichen hinzu, wenn es noch nicht vorhanden ist)
ren * A?Z*
1 -> AZ
12 -> A2Z
1.txt -> AZ.txt
12.txt -> A2Z.txt
123 -> A2Z
123.txt -> A2Z.txt
1234 -> A2Z4
1234.txt -> A2Z4.txt
Ändern Sie die (endgültige) Erweiterung jeder Datei
ren * *.txt
a -> a.txt
b.dat -> b.txt
c.x.y -> c.x.txt
Hängen Sie eine Erweiterung an jede Datei an
ren * *?.bak
a -> a.bak
b.dat -> b.dat.bak
c.x.y -> c.x.y.bak
Entfernen Sie jede zusätzliche Erweiterung nach der ursprünglichen Erweiterung. Beachten Sie, dass ein adäquates ?
verwendet werden muss, um den vollständigen vorhandenen Namen und die anfängliche Erweiterung zu erhalten.
ren * ?????.?????
a -> a
a.b -> a.b
a.b.c -> a.b
part1.part2.part3 -> part1.part2
123456.123456.123456 -> 12345.12345 (note truncated name and extension because not enough `?` were used)
Gleich wie oben, aber filtert Dateien mit Anfangsnamen und/oder Erweiterungen, die länger als 5 Zeichen sind, aus, damit sie nicht abgeschnitten werden. (Offensichtlich könnte ein zusätzliches ?
an beiden Enden von targetMask hinzugefügt werden, um Namen und Erweiterungen mit bis zu 6 Zeichen Länge zu erhalten)
ren ?????.?????.* ?????.?????
a -> a
a.b -> a.b
a.b.c -> a.b
part1.part2.part3 -> part1.part2
123456.123456.123456 (Not renamed because doesn't match sourceMask)
Zeichen nach dem letzten _
im Namen ändern und versuchen, die Erweiterung zu erhalten. (Funktioniert nicht ordnungsgemäß, wenn _
in der Erweiterung vorkommt)
ren *_* *_NEW.*
abcd_12345.txt -> abcd_NEW.txt
abc_newt_1.dat -> abc_newt_NEW.dat
abcdef.jpg (Not renamed because doesn't match sourceMask)
abcd_123.a_b -> abcd_123.a_NEW (not desired, but no simple RENAME form will work in this case)
Jeder Name kann in Komponenten aufgeteilt werden, die durch .
begrenzt sind& Zeichen können nur am Ende jeder Komponente angehängt oder gelöscht werden. Zeichen können nicht am Anfang oder in der Mitte einer Komponente gelöscht oder angehängt werden, während der Rest mit Platzhaltern erhalten bleibt. Substitutionen sind überall erlaubt.
ren ??????.??????.?????? ?x.????999.*rForTheCourse
part1.part2 -> px.part999.rForTheCourse
part1.part2.part3 -> px.part999.parForTheCourse
part1.part2.part3.part4 (Not renamed because doesn't match sourceMask)
a.b.c -> ax.b999.crForTheCourse
a.b.CarPart3BEER -> ax.b999.CarParForTheCourse
Wenn kurze Namen aktiviert sind, dann wird eine sourceMask mit mindestens 8 ?
für den Namen und mindestens 3 ?
für die Erweiterung mit allen Dateien übereinstimmen, da sie immer mit dem kurzen 8.3 Namen übereinstimmt.
ren ????????.??? ?x.????999.*rForTheCourse
part1.part2.part3.part4 -> px.part999.part3.parForTheCourse
Nützlicher Quirk/Bug? zum Löschen von Namenspräfixen
Dieser SuperUser-Beitrag beschreibt, wie ein Satz von Schrägstrichen (/
) verwendet werden kann, um führende Zeichen aus einem Dateinamen zu löschen. Für jedes zu löschende Zeichen ist ein Schrägstrich erforderlich. Ich habe das Verhalten auf einem Windows 10-Rechner bestätigt.
ren "abc-*.txt" "////*.txt"
abc-123.txt --> 123.txt
abc-HelloWorld.txt --> HelloWorld.txt
Diese Technik funktioniert nur, wenn sowohl die Quell- als auch die Zielmaske in doppelte Anführungszeichen eingeschlossen sind. Alle folgenden Formen ohne die erforderlichen Anführungszeichen schlagen mit diesem Fehler fehl: The syntax of the command is incorrect
REM - All of these forms fail with a syntax error.
ren abc-*.txt "////*.txt"
ren "abc-*.txt" ////*.txt
ren abc-*.txt ////*.txt
Das /
kann nicht verwendet werden, um Zeichen in der Mitte oder am Ende eines Dateinamens zu entfernen. Es kann nur führende (Präfix-) Zeichen entfernen. Beachten Sie auch, dass diese Technik nicht mit Ordnernamen funktioniert.
Technisch gesehen funktioniert das /
nicht als Platzhalter. Vielmehr führt es eine einfache Zeichensubstitution durch, aber nach der Substitution erkennt der Befehl REN, dass /
in einem Dateinamen nicht gültig ist, und entfernt die führenden /
-Schrägstriche aus dem Namen. REN gibt einen Syntaxfehler aus, wenn es /
in der Mitte eines Zielnamens erkennt.
Möglicher RENAME-Fehler - ein einziger Befehl kann die gleiche Datei zweimal umbenennen!
Starten in einem leeren Testordner:
C:\test>copy nul 123456789.123
1 file(s) copied.
C:\test>dir /x
Volume in drive C is OS
Volume Serial Number is EE2C-5A11
Directory of C:\test
09/15/2012 07:42 PM <DIR> .
09/15/2012 07:42 PM <DIR> ..
09/15/2012 07:42 PM 0 123456~1.123 123456789.123
1 File(s) 0 bytes
2 Dir(s) 327,237,562,368 bytes free
C:\test>ren *1* 2*3.?x
C:\test>dir /x
Volume in drive C is OS
Volume Serial Number is EE2C-5A11
Directory of C:\test
09/15/2012 07:42 PM <DIR> .
09/15/2012 07:42 PM <DIR> ..
09/15/2012 07:42 PM 0 223456~1.XX 223456789.123.xx
1 File(s) 0 bytes
2 Dir(s) 327,237,562,368 bytes free
REM Expected result = 223456789.123.x
Ich glaube, dass die sourceMask *1*
zuerst mit dem langen Dateinamen übereinstimmt, und die Datei wird in das erwartete Ergebnis 223456789.123.x
umbenannt. RENAME sucht dann weiter nach weiteren zu verarbeitenden Dateien und findet die neu benannte Datei über den neuen kurzen Namen von 223456~1.X
. Die Datei wird dann erneut umbenannt, was das Endergebnis 223456789.123.xx
ergibt.
Wenn ich die 8.3-Namensgenerierung deaktiviere, liefert RENAME das erwartete Ergebnis.
Ich habe noch nicht alle Auslösebedingungen herausgefunden, die vorhanden sein müssen, um dieses merkwürdige Verhalten hervorzurufen. Ich hatte die Befürchtung, dass es möglich sein könnte, einen nicht enden wollenden rekursiven RENAME zu erzeugen, aber es ist mir nicht gelungen, einen solchen zu erzeugen.
Ich glaube, dass alle der folgenden Bedingungen erfüllt sein müssen, um den Fehler zu verursachen. Jeder fehlerhafte Fall, den ich gesehen habe, hatte die folgenden Bedingungen, aber nicht alle Fälle, die die folgenden Bedingungen erfüllten, waren fehlerhaft.
- Kurze 8.3-Namen müssen aktiviert sein
- Die sourceMask muss mit dem ursprünglichen langen Namen übereinstimmen.
- Die anfängliche Umbenennung muss einen kurzen Namen erzeugen, der auch mit der sourceMask übereinstimmt
- Der anfänglich umbenannte kurze Name muss später sortiert werden als der ursprüngliche kurze Name (falls er existierte?)