Ці правила були виявлені після проведення широких випробувань на машині Vista. Жодних тестів з unicode в іменах файлів не робилося.
RENAME вимагає 2 параметрів - sourceMask, за яким слід targetMask. Як sourceMask, так і targetMask можуть містити *
та / або ?
символи. Поведінка макіяжів незначно змінюється між вихідними та цільовими масками.
Примітка - REN може використовуватися для перейменування папки, але символи підказки не дозволяються ні в sourceMask, ні в targetMask при перейменуванні папки. Якщо sourceMask відповідає щонайменше одному файлу, то файли (файли) будуть перейменовані, а папки будуть проігноровані. Якщо sourceMask відповідає лише папкам, а не файлам, то помилка синтаксису генерується, якщо у вихідному чи цільовому вигляді з’являються підмітні знаки. Якщо sourceMask нічого не відповідає, результати помилки "файл не знайдено".
Крім того, під час перейменування файлів підстановки дозволені лише у частині імені файлу sourceMask. Підстановочні знаки не дозволені в шляху, що веде до імені файлу.
sourceMask
SourceMask працює як фільтр, щоб визначити, які файли перейменовані. Підстановочні символи працюють тут так само, як і в будь-якій іншій команді, яка фільтрує назви файлів.
?
- відповідає будь-якому символу 0 або 1, за винятком .
цієї підстановки - жадібна - вона завжди споживає наступного символу, якщо він не є. .
Однак він не відповідає нічого безвідмовно, якщо в кінці імені або якщо наступний символ.
*
- відповідає будь-якому 0 або більше символів, включаючи .
(за винятком нижче). Ця підказка не жадібна. Він збігатиметься так само мало або стільки, скільки потрібно, щоб дати можливість наступним символам збігатися.
Усі символи, що не мають підказки, повинні відповідати самим собі, за винятком кількох спеціальних випадків.
.
- Матч сам, або він може відповідати кінці імені (нічого), якщо більше символів не залишиться. (Примітка - дійсне ім'я Windows не може закінчуватися .
)
{space}
- Матч сам, або він може відповідати кінці імені (нічого), якщо більше символів не залишиться. (Примітка - дійсне ім'я Windows не може закінчуватися {space}
)
*.
в кінці - відповідає будь-якому 0 або більше символів, за винятком .
Закінчення .
може насправді бути будь-якою комбінацією .
та до {space}
тих пір, поки самий останній символ у масці - .
це єдиний і єдиний виняток, де *
не просто відповідає жодному набору символів.
Наведені вище правила не такі складні. Але є ще одне дуже важливе правило, яке робить ситуацію заплутаною: SourceMask порівнюється як з довгим ім'ям, так і з коротким 8.3 ім'ям (якщо воно існує). Це останнє правило може зробити інтерпретацію результатів дуже хитрою, оскільки не завжди очевидно, коли маска збігається через коротке ім'я.
RegEdit можна використовувати для відключення генерації коротких 8,3 імен на томах NTFS, і тоді інтерпретація результатів маски файлів стає набагато більш прямою. Будь-які короткі імена, створені до відключення коротких імен, залишаться.
targetMask
Примітка. Я не робив жодного жорсткого тестування, але, схоже, ці самі правила також працюють для цільової назви команди COPY
Цільова маска вказує нову назву. Він завжди застосовується до повного довгого найменування; Цільова маска ніколи не застосовується до короткого імені 8.3, навіть якщо sourceMask збігається з коротким іменем 8.3.
Наявність або відсутність підстановочних кодів у вихідній масці не впливає на те, як обробляються подвійні символи в цільовій масці.
В подальшому обговоренні - c
будь-який символ , який не є *
, ?
або.
Цільова маска обробляється проти імені джерела суворо зліва направо, без зворотного відстеження.
c
- Просуває позицію в імені джерела до тих пір, поки наступного символу немає, .
і додає c
до цільового імені. (Замінює символ, який був у джерелі c
, але ніколи не замінює .
)
?
- Відповідає наступному символу з довгого імені джерела і додає його до цільового імені, доки наступний символ не є. .
Якщо наступним символом є .
або, якщо в кінці імені джерела, тоді до результату та поточного символу не додається жоден символ положення в назві джерела не змінюється.
*
наприкінці targetMask - додає всі залишилися символи від джерела до цілі. Якщо вже в кінці джерела, то нічого не робить.
*c
- Відповідає всім вихідним символам з поточного положення через останнє значення c
(жадібне до регістру жадне збіг) і додає відповідне набір символів до цільового імені. Якщо c
його не знайдено, додаються всі залишилися символи з джерела, а потім c
- це єдина ситуація, про яку я знаю, де відповідність шаблонів файлів Windows залежить від регістру.
*.
- Відповідає всім вихідним символам з поточного положення через останню появу .
(жадібна відповідність) і додає відповідне набір символів до цільового імені. Якщо .
його не знайдено, додаються всі залишилися символи з джерела, а потім -.
*?
- додає всі інші символи від джерела до цілі. Якщо вже в кінці джерела, то нічого не робить.
.
без *
попереду - переміщує позицію в джерелі через першу появу .
без копіювання жодних символів та додає .
до імені цілі. Якщо .
його не знайдено в джерелі, тоді переходить до кінця джерела та додає .
до цільового імені.
Після того, як targetMask вичерпано, будь-який трейлінг .
і {space}
обрізається в кінці отриманого цільового імені, оскільки імена файлів Windows не можуть закінчуватися .
або{space}
Деякі практичні приклади
Замініть символ на 1-й і 3-й позиціях до будь-якого розширення (додайте 2-го або 3-го символу, якщо його ще немає)
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
Змініть (остаточне) розширення кожного файлу
ren * *.txt
a -> a.txt
b.dat -> b.txt
c.x.y -> c.x.txt
Додайте розширення до кожного файлу
ren * *?.bak
a -> a.bak
b.dat -> b.dat.bak
c.x.y -> c.x.y.bak
Видаліть будь-яке додаткове розширення після початкового розширення. Зауважте, що ?
для збереження повного існуючого імені та початкового розширення необхідно використовувати належне .
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)
Те саме, що вище, але відфільтруйте файли з початковим іменем та / або розширенням довше 5 символів, щоб вони не були усічені. (Очевидно, ви можете додати додатковий ?
на будь-якому кінці targetMask, щоб зберегти імена та розширення довжиною до 6 символів)
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)
Змініть символи за _
прізвищем та спробуйте зберегти розширення. (Не працює належним чином, якщо _
відображається в розширенні)
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)
Будь-яке ім'я може бути розбито на компоненти, які обмежені символами, .
можуть бути додані або видалені лише з кінця кожного компонента. Символи не можуть бути видалені з або додані до початку або середини компонента, зберігаючи залишки за допомогою символів. Заміни дозволені в будь-якому місці.
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
Якщо ввімкнено короткі імена, то sourceMask з принаймні 8 ?
для імені та щонайменше 3 ?
для розширення буде відповідати всім файлам, оскільки він завжди буде відповідати короткому 8.3.
ren ????????.??? ?x.????999.*rForTheCourse
part1.part2.part3.part4 -> px.part999.part3.parForTheCourse
Корисна примха / помилка? для видалення префіксів імен
У цій публікації SuperUser описано, як набір косої риски вперед ( /
) може бути використаний для видалення провідних символів з імені файлу. Для кожного символу потрібно видалити одну косу рису. Я підтвердив поведінку на машині Windows 10.
ren "abc-*.txt" "////*.txt"
abc-123.txt --> 123.txt
abc-HelloWorld.txt --> HelloWorld.txt
Ця методика працює лише в тому випадку, якщо і вихідні, і цільові маски укладені у подвійні лапки. Усі наведені нижче форми без необхідних лапок не відповідають цій помилці: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
/
Не може бути використаний для видалення будь-яких символів в середині або в кінці імені файлу. Він може видаляти лише провідні (префікси) символи.
З технічної точки зору /
це не функціонує як майна. Швидше це робиться проста заміна символів, але потім після підстановки команда REN розпізнає, що /
не відповідає дійсності в імені файлу, і знімає провідні /
риски з імені. REN видає синтаксичну помилку, якщо вона виявляється /
посеред імені цілі.
Можлива помилка RENAME - одна команда може перейменувати один і той же файл двічі!
Починаючи з порожньої тестової папки:
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
Я вважаю, що sourceMask *1*
спочатку відповідає довгому імені файлу, і файл перейменовано на очікуваний результат 223456789.123.x
. Потім RENAME продовжує шукати більше файлів для обробки та знаходить нещодавно названий файл за допомогою нового короткого імені 223456~1.X
. Потім файл знову перейменовують, даючи кінцевий результат 223456789.123.xx
.
Якщо я відключу генерацію імен 8.3, RENAME дає очікуваний результат.
Я не повністю розробив усі умови спрацювання, які повинні існувати, щоб викликати цю дивну поведінку. Я був стурбований тим, що можливо створити ніколи не закінчується рекурсивний RENAME, але я ніколи не зміг викликати його.
Я вважаю, що всі наведені нижче дії повинні бути правдивими, щоб викликати помилку. Кожна випадкова помилка, яку я бачив, мала такі умови, але не всі випадки, які відповідали цим умовам, були помилками.
- Потрібно ввімкнути короткі 8,3 імені
- SourceMask повинен відповідати початковому довгому імені.
- Початкове перейменування повинно генерувати коротке ім'я, яке також відповідає sourceMask
- Початкове перейменоване коротке ім’я повинно впорядковуватися пізніше початкового короткого імені (якщо воно існувало?)