Эти правила были обнаружены после тщательного тестирования на машине Виста. Никаких тестов с юникодом в именах файлов не проводилось._
RENAME требует 2 параметра - маску исходного кода, за которой следует целевая маска. И маска-источник, и целевая маска могут содержать подстановочные знаки *
и/или ?
. Поведение подстановочных знаков незначительно меняется между исходной и целевой масками.
Note - REN может использоваться для переименования папки, но при переименовании папки подстановочные знаки not разрешены ни в исходнойМаске, ни в целевойМаске. Если Маска-источник совпадает, по крайней мере, с одним файлом, то файл(и) будет переименован, а папки проигнорированы. Если маска-источник совпадает только с папками, а не с файлами, то при появлении подстановочных знаков в исходном или целевом коде будет выдана синтаксическая ошибка. Если маска-источник ничему не соответствует, то выдается ошибка “файл не найден”.
При переименовании файлов подстановочные знаки разрешены только в части имени файла в маске-источнике. Подстановочные знаки не допускаются в пути, ведущем к имени файла.
маска-источник
Маска-источник работает как фильтр для определения того, какие файлы переименованы. Подстановочные знаки здесь работают так же, как и с любой другой командой, которая фильтрует имена файлов.
?
- Совпадает с любым 0 или 1 символом except .
Этот шаблон жадный - он всегда потребляет следующий символ, если это не .
Однако он не будет совпадать ни с чем без сбоев, если в конце имени или если следующий символ .
*
- Совпадает с любым 0 или более символами including .
(за одним исключением ниже). Этот символ подстановки не является жадным. Он будет совпадать так мало или так много, как необходимо для того, чтобы последующие символы совпадали.
Все не-символы подстановки должны совпадать сами по себе, за исключением нескольких особых случаев.
.
- Совпадает сам по себе или может совпадать с концом имени (ничего), если больше не осталось символов. (Примечание - действительное имя Windows не может заканчиваться на .
)
{space}
- Совпадает само по себе или может совпадать с концом имени (ничего), если больше не осталось символов. (Обратите внимание - действительное имя Windows не может заканчиваться на {space}
)
*.
в конце - Совпадает с любыми 0 или более символами except .
Окончание .
на самом деле может быть любой комбинацией .
и {space}
до тех пор, пока самый последний символ в маске - .
Это единственное и неповторимое исключение, где *
просто не совпадает с любым набором символов.
Вышеприведенные правила не настолько сложны. Но есть еще одно очень важное правило, которое вносит путаницу в ситуацию: Маска-источник сравнивается как с длинным именем, так и с коротким именем 8.3 (если оно существует). Это последнее правило может сделать интерпретацию результатов очень сложной, потому что не всегда очевидно, когда маска сравнивается через короткое имя.
Можно использовать RegEdit для отключения генерации коротких имен 8.3 на томах NTFS, при этом интерпретация результатов файловой маски будет гораздо более простой. Любые короткие имена, которые были сгенерированы до отключения коротких имен, останутся.
targetMask
Note - я не проводил строгого тестирования, но, похоже, эти же правила работают и для целевого имени COPY-запятой
The targetMask задает новое имя. Она всегда применяется к полному длинному имени; targetMask никогда не применяется к короткому имени 8.3, даже если исходнаяМаска совпала с коротким именем 8.3.
Наличие или отсутствие подстановочных знаков в исходной Маске не влияет на то, как обрабатываются подстановочные знаки в целевой Маске.
В следующем обсуждении - c
представляет любой символ, который не является *
, ?
или .
ЦелеваяМаска обрабатывается против имени источника строго слева направо без обратной связи.
c
- Улучшение позиции внутри имени источника только в том случае, если исходный символ не является .
, и всегда добавляет c
к целевому имени. (Заменяет символ, который был в источнике, на c
, но никогда не заменяет .
)
?
- Совпадает со следующим символом длинного имени источника и добавляет его к целевому имени до тех пор, пока исходный символ не равен .
Если следующий символ равен .
или если он находится в конце имени источника, то к результату не добавляется ни один символ, а текущая позиция внутри имени источника остается неизменной.
*
в конце целевойМаски - Добавляет все оставшиеся символы из источника в целевой. Если уже в конце источника, то ничего не делает.
*c
- Сопоставляет все символы источника от текущей позиции до последнего прохождения c
(жадное совпадение с учетом регистра) и добавляет соответствующий набор символов к целевому имени. Если c
не найдено, то добавляются все оставшиеся символы из источника, а затем c
Это единственная известная мне ситуация, в которой соответствие файловых шаблонов Windows чувствительно к регистру.
*.
- Сопоставляет все исходные символы от текущей позиции до last окклюзии .
(жадное совпадение) и добавляет соответствующий набор из Символы к имени цели. Если .
не найдено, то добавляются все оставшиеся символы из источника, а затем .
*?
- добавляются все оставшиеся символы из источника к целевому имени. Если уже в конце источника, то ничего не происходит.
.
без *
впереди - Продвигается позиция в источнике через первое появление .
без копирования каких-либо символов, и добавляет .
к целевому имени. Если .
не найдено в источнике, то перемещается в конец источника и добавляет .
к целевому имени.
После того, как целевая маска исчерпана, любой трейлинг .
и {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
Имя, как указано выше, но отфильтровывайте файлы с начальным именем и/или расширением длиннее 5 символов, чтобы они не были усечены. (Очевидно, что можно добавить дополнительный ?
с обоих концов целевойМаски для сохранения имен и расширений до 6 символов в длину)
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)
Измените символы после последнего _
в имени и попытайтесь сохранить расширение. (Не работает, если _
появляется в расширении)
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)
Если включены короткие имена, то маска-источник с как минимум 8 ?
для имени и как минимум 3 ?
для расширения будет соответствовать всем файлам, потому что всегда будет соответствовать короткому имени 8.3.
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
Полезная причуда/ошибка? для удаления префиксов имен
Этот пост SuperUser описывает, как набор прямых косых черт (/
) может быть использован для удаления ведущих символов из имени файла. Для каждого удаляемого символа требуется одна косая черта. Я подтвердил поведение на машине с Windows 10.
ren ????????.??? ?x.????999.*rForTheCourse
part1.part2.part3.part4 -> px.part999.part3.parForTheCourse
Эта техника работает только в том случае, если и исходная и целевая маски заключены в двойные кавычки. Все следующие формы без необходимых кавычек не справляются с этой ошибкой: The syntax of the command is incorrect
ren "abc-*.txt" "////*.txt"
abc-123.txt --> 123.txt
abc-HelloWorld.txt --> HelloWorld.txt
Нельзя использовать /
для удаления любых символов в середине или в конце имени файла. Он может удалять только ведущие (префиксные) символы. Обратите внимание, что эта техника не работает с именами папок.
Технически /
не работает как подстановочный символ. Скорее она делает простую подстановку символов, но после подстановки команда REN распознает, что /
недействителен в имени файла, и удаляет ведущие /
косая черта из имени. REN дает синтаксическую ошибку, если обнаруживает /
в середине целевого имени.
Возможная ошибка RENAME - одна команда может переименовать один и тот же файл дважды!
Запуск в пустой папке теста:
REM - All of these forms fail with a syntax error.
ren abc-*.txt "////*.txt"
ren "abc-*.txt" ////*.txt
ren abc-*.txt ////*.txt
Думаю, исходная маска *1*
сначала совпадает с длинным именем файла, а файл переименовывается на ожидаемый результат 223456789.123.x
. Затем RENAME продолжает искать больше файлов для обработки и находит новый файл с новым коротким именем 223456~1.X
. Затем файл переименовывается снова, давая конечный результат 223456789.123.xx
.
Если я отключу генерацию имени 8.3, то RENAME дает ожидаемый результат.
Я не полностью проработал все условия триггера, которые должны существовать, чтобы вызвать такое странное поведение. Меня беспокоило, что можно создать бесконечное рекурсивное РЕНАМЕ, но я никогда не мог его вызвать. 0x2 и 0x2 и я считаю, что все нижеследующее должно быть правдой, чтобы вызвать ошибку. Каждый прослушиваемый случай, который я видел, имел следующие условия, но не все случаи, которые удовлетворяли следующим условиям, были прослушиваны.
- Должны быть включены короткие имена 8.3
- Маска источника должна совпадать с оригинальным длинным именем.
- Первоначальное переименование должно генерировать короткое имя, которое также совпадает с маской-источником
- Первоначальное переименованное короткое имя должно сортироваться позже, чем оригинальное короткое имя (если оно существовало?).