Queste regole sono state scoperte dopo numerosi test su una macchina Vista. Non sono stati eseguiti test con Unicode nei nomi dei file.
RENAME richiede 2 parametri: una maschera di origine, seguita da una maschera di destinazione. Sia sourceMask che targetMask possono contenere *
e / o ?
caratteri jolly. Il comportamento dei caratteri jolly cambia leggermente tra le maschere di origine e di destinazione.
Nota : REN può essere utilizzato per rinominare una cartella, ma i caratteri jolly non sono consentiti in sourceMask o targetMask quando si rinomina una cartella. Se sourceMask corrisponde ad almeno un file, i file verranno rinominati e le cartelle verranno ignorate. Se sourceMask corrisponde solo alle cartelle e non ai file, viene generato un errore di sintassi se i caratteri jolly vengono visualizzati nell'origine o nella destinazione. Se sourceMask non corrisponde a nulla, si verifica un errore "file non trovato".
Inoltre, quando si rinomina un file, i caratteri jolly sono consentiti solo nella parte del nome file di sourceMask. I caratteri jolly non sono consentiti nel percorso che porta al nome del file.
sourceMask
SourceMask funziona come filtro per determinare quali file vengono rinominati. I caratteri jolly funzionano qui come con qualsiasi altro comando che filtra i nomi dei file.
?
- Corrisponde a qualsiasi carattere 0 o 1 tranne .
questo jolly è avido - consuma sempre il carattere successivo se non è un .
Tuttavia non corrisponderà a nulla senza errori se alla fine del nome o se il carattere successivo è un.
*
- Corrisponde a qualsiasi 0 o più caratteri incluso .
(con un'eccezione di seguito). Questo jolly non è avido. Corrisponderà alla quantità necessaria o ridotta per consentire la corrispondenza dei caratteri successivi.
Tutti i caratteri non jolly devono corrispondere a se stessi, con alcune eccezioni di casi speciali.
.
- Corrisponde a se stesso o può corrispondere alla fine del nome (nulla) se non rimangono più caratteri. (Nota: un nome Windows valido non può terminare con .
)
{space}
- Corrisponde a se stesso o può corrispondere alla fine del nome (nulla) se non rimangono più caratteri. (Nota: un nome Windows valido non può terminare con {space}
)
*.
alla fine - Corrisponde a qualsiasi 0 o più caratteri tranne .
La terminazione .
può effettivamente essere una qualsiasi combinazione di .
e {space}
fintanto che l'ultimo carattere nella maschera è .
Questa è l'unica e unica eccezione in cui *
non corrisponde semplicemente alcun set di caratteri.
Le regole di cui sopra non sono così complesse. Ma c'è un'altra regola molto importante che rende la situazione confusa: sourceMask viene confrontato sia con il nome lungo che con il nome breve 8.3 (se esiste). Quest'ultima regola può rendere molto difficile l'interpretazione dei risultati, perché non è sempre ovvio quando la maschera corrisponde con il nome breve.
È possibile utilizzare RegEdit per disabilitare la generazione di nomi 8.3 brevi sui volumi NTFS, a quel punto l'interpretazione dei risultati della maschera file è molto più semplice. Rimarranno tutti i nomi brevi generati prima di disabilitare i nomi brevi.
targetMask
Nota: non ho eseguito test rigorosi, ma sembra che queste stesse regole funzionino anche per il nome target del comando COPY
TargetMask specifica il nuovo nome. Viene sempre applicato al nome lungo completo; TargetMask non viene mai applicato al nome breve 8.3, anche se sourceMask corrisponde al nome breve 8.3.
La presenza o l'assenza di caratteri jolly nella maschera di origine non ha alcun impatto sul modo in cui i caratteri jolly vengono elaborati nella maschera di destinazione.
Nella seguente discussione - c
rappresenta qualsiasi carattere che non è *
, ?
o.
TargetMask viene elaborato in base al nome della sorgente rigorosamente da sinistra a destra senza back-tracking.
c
- Fa avanzare la posizione all'interno del nome della fonte fintanto che il carattere successivo non lo è .
e si aggiunge c
al nome della destinazione. (Sostituisce il personaggio che era nella fonte con c
, ma non sostituisce mai .
)
?
- Abbina il carattere successivo dal nome lungo della fonte e lo aggiunge al nome di destinazione purché il carattere successivo non lo sia. .
Se il carattere successivo è .
o se alla fine del nome della fonte non viene aggiunto alcun carattere al risultato e al corrente la posizione all'interno del nome della sorgente è invariata.
*
alla fine di targetMask - Aggiunge tutti i caratteri rimanenti dall'origine alla destinazione. Se già alla fine della fonte, quindi non fa nulla.
*c
- Corrisponde a tutti i caratteri sorgente dalla posizione corrente all'ultima occorrenza di c
(corrispondenza golosa con distinzione tra maiuscole e minuscole) e aggiunge il set di caratteri corrispondente al nome di destinazione. Se c
non viene trovato, vengono aggiunti tutti i caratteri rimanenti dall'origine, seguiti da c
Questa è l'unica situazione che conosco in cui la corrispondenza del modello di file di Windows è sensibile al maiuscolo / minuscolo.
*.
- Abbina tutti i personaggi di origine dalla posizione corrente all'ultima occorrenza di .
(partita golosa) e aggiunge il set di caratteri corrispondente al nome di destinazione. Se .
non viene trovato, vengono aggiunti tutti i caratteri rimanenti dalla fonte, seguiti da.
*?
- Aggiunge tutti i personaggi rimanenti dalla sorgente al bersaglio. Se già alla fine della fonte non fa nulla.
.
senza *
davanti - Fa avanzare la posizione nella fonte attraverso la prima occorrenza .
senza copiare alcun carattere e si aggiunge .
al nome di destinazione. Se .
non viene trovato nella fonte, avanza fino alla fine della fonte e si aggiunge .
al nome di destinazione.
Dopo che il targetMask è stato esaurito, tutti i finali .
e {space}
vengono eliminati alla fine del nome di destinazione risultante perché i nomi dei file di Windows non possono terminare con .
o{space}
Alcuni esempi pratici
Sostituisci un personaggio nella prima e terza posizione prima di qualsiasi estensione (aggiunge un secondo o un terzo carattere se non esiste ancora)
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
Cambia l'estensione (finale) di ogni file
ren * *.txt
a -> a.txt
b.dat -> b.txt
c.x.y -> c.x.txt
Aggiungi un'estensione a ogni file
ren * *?.bak
a -> a.bak
b.dat -> b.dat.bak
c.x.y -> c.x.y.bak
Rimuovere eventuali estensioni extra dopo l'estensione iniziale. Si noti che è ?
necessario utilizzare un'adeguata per preservare l'intero nome esistente e l'estensione iniziale.
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)
Come sopra, ma filtra i file con nome iniziale e / o estensione più lunghi di 5 caratteri in modo che non vengano troncati. (Ovviamente potrebbe aggiungere un ulteriore ?
su entrambe le estremità di targetMask per preservare nomi ed estensioni fino a 6 caratteri)
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)
Cambia i caratteri dopo l'ultimo _
nel nome e prova a preservare l'estensione. (Non funziona correttamente se _
appare nell'estensione)
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)
Qualsiasi nome può essere suddiviso in componenti delimitati da .
Personaggi che possono essere aggiunti o eliminati solo dalla fine di ciascun componente. I caratteri non possono essere eliminati o aggiunti all'inizio o al centro di un componente preservando il resto con caratteri jolly. Le sostituzioni sono consentite ovunque.
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
Se i nomi brevi sono abilitati, allora un sourceMask con almeno 8 ?
per il nome e almeno 3 ?
per l'estensione corrisponderà a tutti i file perché corrisponderà sempre al nome breve 8.3.
ren ????????.??? ?x.????999.*rForTheCourse
part1.part2.part3.part4 -> px.part999.part3.parForTheCourse
Quirk / bug utili? per eliminare i prefissi dei nomi
Questo post di SuperUser descrive come utilizzare una serie di barre ( /
) per eliminare i caratteri iniziali da un nome file. È richiesta una barra per ogni carattere da eliminare. Ho confermato il comportamento su un computer Windows 10.
ren "abc-*.txt" "////*.txt"
abc-123.txt --> 123.txt
abc-HelloWorld.txt --> HelloWorld.txt
Questa tecnica funziona solo se le maschere di origine e di destinazione sono racchiuse tra virgolette doppie. Tutti i seguenti moduli senza virgolette richieste non riescono con questo errore: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
Non /
può essere usato per rimuovere alcun carattere nel mezzo o alla fine di un nome di file. Può solo rimuovere i caratteri iniziali (prefisso).
Tecnicamente /
non funziona come jolly. Piuttosto sta effettuando una semplice sostituzione del carattere, ma dopo la sostituzione, il comando REN riconosce che /
non è valido in un nome di file e rimuove le /
barre iniziali dal nome. REN genera un errore di sintassi se viene rilevato /
nel mezzo di un nome di destinazione.
Possibile bug RENAME - un singolo comando può rinominare lo stesso file due volte!
A partire da una cartella di prova vuota:
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
Credo che sourceMask *1*
corrisponda prima al nome del file lungo e il file viene rinominato con il risultato previsto di 223456789.123.x
. RENAME continua quindi a cercare altri file da elaborare e trova il file appena nominato tramite il nuovo nome breve di 223456~1.X
. Il file viene quindi rinominato nuovamente dando il risultato finale di 223456789.123.xx
.
Se disabilito la generazione del nome 8.3, RENAME dà il risultato atteso.
Non ho elaborato completamente tutte le condizioni di innesco che devono esistere per indurre questo strano comportamento. Temevo che potesse essere possibile creare un RENAME ricorsivo senza fine, ma non sono mai stato in grado di indurlo.
Credo che tutto ciò che segue debba essere vero per indurre il bug. Ogni caso con problemi che ho visto presentava le seguenti condizioni, ma non tutti i casi che soddisfacevano le seguenti condizioni erano stati risolti.
- I nomi brevi 8.3 devono essere abilitati
- SourceMask deve corrispondere al nome lungo originale.
- La ridenominazione iniziale deve generare un nome breve che corrisponda anche a sourceMask
- Il nome breve rinominato iniziale deve essere ordinato più tardi del nome breve originale (se esisteva?)