Как команда Windows RENAME (REN) интерпретирует подстановочные знаки?
Встроенное средство HELP не помогает - оно вообще не обращается к групповым символам.
Microsoft TechNet XP онлайн помощь не намного лучше. Вот все, что нужно сказать о подстановочных знаках:
«Вы можете использовать подстановочные знаки (
*
и?
) в любом параметре имени файла. Если вы используете подстановочные знаки в имени файла2, символы, представленные подстановочными знаками, будут идентичны соответствующим символам в имени файла1».
Немного помощи - есть много способов, которыми это утверждение может быть истолковано.
Мне иногда удавалось успешно использовать подстановочные знаки в параметре filename2 , но это всегда было методом проб и ошибок. Я не смог предвидеть, что работает, а что нет. Часто мне приходилось прибегать к написанию небольшого пакетного скрипта с циклом FOR, который анализирует каждое имя, чтобы я мог создавать каждое новое имя по мере необходимости. Не очень удобно.
Если бы я знал правила обработки подстановочных знаков, то решил, что мог бы использовать команду RENAME более эффективно, не прибегая к пакетной обработке так часто. Конечно, знание правил также будет полезно для пакетной разработки.
(Да - это тот случай, когда я публикую парный вопрос и ответ. Я устал от незнания правил и решил поэкспериментировать самостоятельно. Я полагаю, что многим другим может быть интересно то, что я обнаружил)
источник
*
Windows. Это имеет огромные последствия. Хотел бы я знать об этом сайте; это могло бы облегчить мое расследование. Правила MSDOS7 значительно отличаются от старых правил DOS перед длинными именами файлов, и они являются шагом в направлении того, как Windows справляется с этим. Я обнаружил правила DOS с длинными именами файлов, и они были бесполезны для моего расследования.Ответы:
Эти правила были обнаружены после тщательного тестирования на компьютере с Vista. С юникодом в именах файлов не проводилось никаких тестов.
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.
TargetMask указывает новое имя. Это всегда применяется к полному длинному имени; TargetMask никогда не применяется к короткому имени 8.3, даже если sourceMask соответствует короткому имени 8.3.
Наличие или отсутствие подстановочных знаков в sourceMask не влияет на то, как подстановочные знаки обрабатываются в targetMask.
В последующем обсуждении -
c
любой символ , который не является*
,?
или.
TargetMask обрабатывается относительно имени источника строго слева направо без обратного отслеживания.
c
- Продвигает позицию в пределах имени источника до тех пор, пока следующий символ не будет,.
и добавляетсяc
к целевому имени. (Заменяет символ, который был в источникеc
, но никогда не заменяет.
)?
- Соответствует следующему символу из длинного имени источника и добавляет его к целевому имени до тех пор, пока следующий символ не будет..
Если следующий символ.
или, если в конце имени источника, то ни один символ не добавляется к результату и текущему позиция в названии источника не изменилась.*
в конце targetMask - добавляет все оставшиеся символы от источника к цели. Если уже в конце источника, то ничего не делает.*c
- Сопоставляет все исходные символы от текущей позиции до последнего вхожденияc
(жадное совпадение с учетом регистра) и добавляет соответствующий набор символов к целевому имени. Еслиc
он не найден, то добавляются все оставшиеся символы из источника, после чего следует «c
Это единственная известная мне ситуация, когда при сопоставлении шаблонов файлов Windows учитывается регистр символов».*.
- Сопоставляет все исходные символы от текущей позиции до последнего вхождения.
(жадное совпадение) и добавляет соответствующий набор символов к целевому имени. Если.
не найден, то все остальные символы из источника добавляются, а затем.
*?
- Добавляет все оставшиеся символы от источника к цели. Если уже в конце источника, то ничего не делает..
без*
впереди - продвигает позицию в источнике через первое вхождение.
без копирования каких-либо символов и добавляет.
к целевому имени. Если.
он не найден в источнике, он переходит к концу источника и добавляется.
к целевому имени.После того, как targetMask был исчерпан, любые конечные
.
и{space}
обрезанные в конце конечного имени цели, потому что имена файлов Windows не могут заканчиваться.
или{space}
Некоторые практические примеры
Замените символ в 1-й и 3-й позициях перед любым расширением (добавляет 2-й или 3-й символ, если он еще не существует)
Изменить (окончательное) расширение каждого файла
Добавить расширение для каждого файла
Удалите все дополнительные расширения после исходного расширения. Обратите внимание, что
?
для сохранения полного существующего имени и начального расширения необходимо использовать адекватное .То же, что и выше, но отфильтровывать файлы с начальным именем и / или расширением длиннее 5 символов, чтобы они не усекались. (Очевидно, можно добавить дополнительный
?
на любом конце targetMask, чтобы сохранить имена и расширения длиной до 6 символов)Измените символы после последней
_
в имени и попытайтесь сохранить расширение. (Не работает должным образом, если_
появляется в расширении)Любое имя может быть разбито на компоненты, разделенные
.
символами, которые могут быть добавлены или удалены только в конце каждого компонента. Символы не могут быть удалены или добавлены в начало или в середину компонента, сохраняя остаток с подстановочными знаками. Замены разрешены где угодно.Если короткие имена включены, то sourceMask с по крайней мере 8
?
для имени и по крайней мере 3?
для расширения будет соответствовать всем файлам, потому что оно всегда будет соответствовать короткому имени 8.3.Полезная причуда / ошибка? для удаления префиксов имен
Этот пост SuperUser описывает, как набор косых черт (
/
) может быть использован для удаления начальных символов из имени файла. Для удаления каждого символа требуется один слеш. Я подтвердил поведение на компьютере с Windows 10.Этот метод работает, только если исходная и целевая маски заключены в двойные кавычки. Все следующие формы без нужных кавычек завершаются с этой ошибкой:
The syntax of the command is incorrect
/
Не может быть использован для удаления любых символов в середине или в конце имени файла. Он может удалять только начальные (префиксные) символы.Технически
/
это не работает как подстановочный знак. Скорее, он выполняет простую подстановку символов, но затем после подстановки команда REN распознает/
недопустимое имя файла и удаляет/
начальные косые черты из имени. REN дает синтаксическую ошибку, если обнаруживает/
в середине целевого имени.Возможная ошибка RENAME - одна команда может дважды переименовать один и тот же файл!
Начиная с пустой тестовой папки:
Я считаю, что sourceMask
*1*
сначала соответствует длинному имени файла, и файл переименовывается в ожидаемый результат223456789.123.x
. Затем RENAME продолжает поиск файлов для обработки и находит новый файл с новым коротким именем223456~1.X
. Затем файл снова переименовывается, давая окончательный результат223456789.123.xx
.Если я отключу генерацию имени 8.3, то RENAME даст ожидаемый результат.
Я не полностью проработал все условия триггера, которые должны существовать, чтобы вызвать это странное поведение. Я был обеспокоен тем, что возможно создать бесконечное рекурсивное RENAME, но я так и не смог вызвать его.
Я считаю, что все следующее должно быть правдой, чтобы вызвать ошибку. В каждом случае ошибки, который я видел, были следующие условия, но не все случаи, которые удовлетворяли следующим условиям, были ошибками.
источник
REN /?
.Copy of
префикс, используя непонятную технику прямого слеша:ren "Copy of *.txt" "////////*"
Как и в exebook, вот реализация C # для получения целевого имени файла из исходного файла.
Я нашел 1 маленькую ошибку в примерах dbenham:
Вот код:
А вот метод тестирования NUnit для тестирования примеров:
источник
Мне удалось написать этот код на бейсике, чтобы замаскировать подстановочные имена файлов:
источник
Может быть, кто-то может найти это полезным. Этот код JavaScript основан на ответе dbenham выше.
Я не
sourceMask
очень много тестировал , ноtargetMask
соответствует всем примерам, приведенным dbenham.источник