Добавление второго расширения файла к файлу с определенным префиксом - PullRequest
0 голосов
/ 30 сентября 2019

У меня есть следующие файлы для изменения xxx.001, xxx.002 и т. Д. Путем добавления .txt в конце имени файла. Для этого я использую следующую команду:

rename XXXX*.* *?.txt

Однако он вставляет .txt дважды, а не один раз.

1 Ответ

0 голосов
/ 01 октября 2019

Решением является переименование файлов, соответствующих шаблону с подстановочными знаками, с использованием цикла FOR .

for %%I in (xxx*) do ren "%%I" "%%I.txt"

Этот цикл FOR в пакетном файле выполняет поиск в текущем каталоге. для не скрытых файлов, имя файла которых совпадает с шаблоном подстановки xxx*. Каждое имя файла, соответствующее шаблону с подстановочными знаками, присваивается переменной цикла I без пути к файлу и без двойных кавычек даже при наличии пробела или одного из этих символов &()[]{}^=;!'+,`~, требующих заключить имя файла в двойные кавычки. Команда REN переименовывает файл, добавляя .txt.

Проблема этой простой командной строки заключается в том, что список имен файлов в текущем каталоге изменяется, в то время как команда FOR перебирает список имен файлов, соответствующих шаблону подстановки. Тем не менее эта командная строка может работать на носителе в формате NTFS, поскольку NTFS хранит записи каталога в локальном алфавитном порядке, а сортировка имен файлов в текущем каталоге не меняется, поскольку к некоторым именам файлов добавляется только .txt. Но на носителях, отформатированных в FAT16, FAT32 или exFAT , эта простая командная строка может не работать должным образом. Некоторые файлы могут быть переименованы более одного раза, а другие могут быть пропущены из-за того, что записи каталогов на дисках FAT не хранятся отсортированными, как на дисках NTFS.

Решение состоит в том, чтобы сначала получить список файлов для переименования в памяти, а затемпереименовывать один за другим. Тогда список имен файлов больше не изменяется во время итераций цикла. Это может быть достигнуто с помощью следующей командной строки:

for /F "eol=| delims=" %%I in ('dir "xxx*" /A-D /B 2^>nul') do ren "%%I" "%%I.txt"

FOR с опцией /F запускается в этом случае в фоновом режиме еще один командный процесс, запущенный с %ComSpec% /c и добавленная командная строкауказано между '. Это означает, что при установке Windows на C:\Windows FOR выполняется в фоновом режиме:

C:\Windows\System32\cmd.exe /c dir "xxx*" /A-D /B 2>nul

Прочтите статью Microsoft о , используя операторы перенаправления команд , для объяснения 2>nul. Оператор перенаправления > должен быть экранирован с помощью символа вставки ^ в FOR командной строке, чтобы интерпретироваться как литеральный символ, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR , котораявыполняет встроенную командную строку dir в отдельном командном процессе, запущенном в фоновом режиме.

DIR выполняется cmd.exe в фоновом поиске

  • в текущем каталоге
  • для имен файлов не скрытых и скрытых файлов из-за опции /A-D (атрибут, а не каталог)
  • , совпадающей с шаблоном подстановки xxx*, то есть любым именем файла, начинающимся с xxx,
  • и выводит в голом формате только имя файла + расширение файла без пути к файлу, никогда не заключенное в " из-за опции /B.

Сообщение об ошибке, выводимое DIR , если не удается найти какую-либо запись каталога, соответствующую этим критериям, для обработки STDERR перенаправляется на устройство NUL для подавленияit.

Вывод DIR (список имен файлов) для обработки STDOUT фонового командного процесса захватывается FOR и обрабатывается строкойстрока после начала cmd.exe прекратилась сама. Это важное отличие от первой командной строки. Список имен файлов теперь полностью находится в памяти, и FOR выполняет итерацию по этому списку имен файлов, больше не меняющихся во время итераций цикла.

FOR с параметром /F игнорирует пустые строки, которых нет в захваченном списке имен файлов.

FOR с параметром /F будет разбивать каждую строку на подстроки с использованием горизонтальной табуляции и обычного пространства в качестве разделителей строк. Такое поведение разделения строк здесь не требуется, если имя файла содержит один или несколько пробелов. По этой причине delims= используется в конце строки аргумента параметров для определения пустого списка разделителей, который полностью отключает режим разделения строк.

FOR с параметром /F будет игнорировать всю строку, если первая подстрока после разбиения строки (в данном случае не делается) имеет точку с запятой в качестве первого символа. Имя файла может начинаться с ;, и по этой причине eol=| используется для определения вертикальной черты как символа конца строки, который ни один файл не может содержать в своем имени файла. Таким образом, FOR никогда не игнорирует имя файла. В этом случае при DIR с выводом только имен файлов, начинающихся с xxx, можно также использовать значение по умолчанию eol=;, и поэтому eol=| не потребуется.

Итак FOR назначает одно имя файла после другого вывода с помощью DIR без пути к переменной цикла I и запускает команду REN , чтобы переименовать этот файл, добавив .txt.

Но остается одна проблема, если в текущем каталоге уже есть файлы, начинающиеся с xxx и имеющие уже расширение .txt, поскольку эти файлы будут также выводиться DIR и, следовательно, обрабатыватьсяна FOR , что приводит к добавлению еще одного .txt.

Существует как минимум два решения, позволяющих избежать переименования файлов с уже имеющимся расширением .txt:

  1. Выходные данные команды DIR фильтруются с помощью FINDSTR , который выводит только все имена файлов, НЕ заканчивающиеся без учета регистра и буквально интерпретируемой строки .txt пользователем using:

    for /F "eol=| delims=" %%I in ('dir "xxx*" /A-D /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /E /L /I /V /C:".txt"') do ren "%%I" "%%I.txt"
    
  2. Дополнительное условие IF используется для сравнения нечувствительного к регистру расширения текущего имени файла со строкой .txt, чтобы определить, является ли REN должно быть выполнено для текущего файла с использованием:

    for /F "eol=| delims=" %%I in ('dir "xxx*" /A-D /B 2^>nul') do if /I not "%%~xI" == ".txt" ren "%%I" "%%I.txt"
    

Откройте окно с командной строкой , выполните следующие команды и прочитайтеполностью все справочные страницы, отображаемые для каждой команды, очень тщательно для получения дополнительной информации об используемых командах и их параметрах.

  • dir /?
  • findstr /?
  • for /?
  • if /?
  • ren /?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...