Как убрать цифры из начала имени файла? - PullRequest
0 голосов
/ 05 января 2019

Мне нужно переименовать имя файла, подобное этому 7612372 filename 50x50.jpg, в это filename 50x50.jpg, удалив все цифры в начале имени файла. Цифра может быть переменной.

Мне нужно интегрировать это в существующий пакетный файл, запускаемый из командной строки Windows.

Ответы [ 4 ]

0 голосов
/ 06 января 2019

Более простое решение - использовать

  • все цифры и пробел в качестве разделителей и
  • токенов = *

:: Q:\Test\2019\01\06\SO_54054587.cmd
for /F "delims=" %%A in (
    'dir "* *" /A-D-H /B 2^>nul'
) do for /F "tokens=* delims=0123456789 " %%B in (
    "%%A"
) do ren "%%A" "%%B"

это удалит всех ведущих разделителей, в то время как не разделяет оставшуюся часть имени файла.

Как и другие ответы, это не будет учитывать уже существующее сокращенное имя файла.

0 голосов
/ 05 января 2019

Я предлагаю следующий код партии для этой задачи:

@echo off
for /F "delims=" %%A in ('dir "* *" /A-D-H /B 2^>nul') do for /F "tokens=1*" %%B in ("%%A") do ren "%%A" "%%C"
pause

Команда FOR выполняется с cmd.exe /C (точнее %ComSpec% /C) в отдельном командном процессе в фоновом режиме командной строки:

dir "* *" /A-D-H /B 2>nul

DIR вывод для обработки STDOUT этого фонового командного процесса

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

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

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

FOR захватывает все выходные строки для обработки STDOUT запущенного командного процесса и обрабатывает эти строки после завершения самого запуска cmd.exe. Для этой задачи переименования файлов очень важно, чтобы FOR выполнялся со списком имен файлов, перехваченных перед переименованием файлов, иначе записи каталога изменились бы, пока FOR обращается к ним. По этой причине for не может использоваться непосредственно в этом случае, поскольку for будет обрабатывать список записей каталога * *, в то время как этот список изменяется при каждом успешном переименовании файла. Результатом будут файлы, которые не переименовываются или переименовываются несколько раз, или даже бесконечный цикл выполнения, в зависимости от файловой системы (NTFS или файловой системы FAT, такой как FAT32 или ExFAT).

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

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

Имя файла, присвоенное переменной цикла A, обозначается %%A как строка во внутреннем цикле FOR , которая разбивает имя файла на две подстроки (токены). Первая подстрока - это номер, присвоенный указанной переменной цикла B. Вторая подстрока после первой последовательности пробелов (табуляция в имени файла невозможна) присваивается без дальнейшего разделения на следующую переменную цикла C в соответствии с ASCII таблицей . Другими словами, в имени файла 7612372 filename 50x50.jpg переменная цикла B содержит 7612372, а filename 50x50.jpg назначается переменной цикла C.

Команда REN переименовывает файл, ссылаясь на полное имя файла, назначенное переменной цикла A, на часть после первой последовательности пробелов, назначенную переменной цикла C.

Добавлена ​​команда PAUSE в конце, чтобы увидеть сообщение об ошибке, выводимое командой REN , если переименование файла не удалось. Ничего не выводится, кроме приглашения PAUSE , все файлы могут быть успешно переименованы.

Пакетный код может быть дополнительно расширен с помощью FINDSTR в качестве фильтра, чтобы убедиться, что файл для переименования действительно начинается с одной или нескольких цифр до первого пробела с помощью этого кода:

@echo off
for /F "delims=" %%A in ('dir "* *" /A-D-H /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /R /C:"^[0123456789][0123456789]* "') do for /F "tokens=1*" %%B in ("%%A") do ren "%%A" "%%C"
pause

Еще один вариант переименования файла с именем 03T30 NAME T ALL 40X40X2 - Copy.JPG на T30 NAME T ALL 40X40X2 - Copy.JPG:

@echo off
for /F "delims=" %%A in ('dir /A-D-H /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /R "^[0123456789][0123456789]*"') do for /F "tokens=* delims=0123456789 " %%B in ("%%A") do ren "%%A" "%%B"
pause

DIR выводит имена всех не скрытых файлов в текущем каталоге. Эти выходные данные перенаправляются как входные данные для FINDSTR , который проверяет, начинается ли имя файла с одной или нескольких цифр. Только эти имена файлов выводятся в STDOUT фонового командного процесса, который затем обрабатывается FOR .

Внутренний FOR интерпретирует все цифры и пробел как строковые разделители из-за delims=0123456789 и присваивает все после первой последовательности цифр или пробелов переменной цикла B из-за tokens=*. Таким образом, переменная цикла B содержит filename 50x50.jpg с 7612372 filename 50x50.jpg, присвоенным A и T30 NAME T ALL 40X40X2 - Copy.JPG для имени файла 03T30 NAME T ALL 40X40X2 - Copy.JPG.

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

  • dir /?
  • echo /?
  • findstr /?
  • for /?
  • pause /?
  • ren /?

PS: Я рекомендую использовать условно-бесплатный файловый менеджер Total Commander, который имеет встроенный инструмент многократного переименования для переименования файлов и папок для людей, не имеющих опыта программирования. Загрузите, установите и запустите Total Commander, перейдите в папку, содержащую все эти файлы, нажмите Ctrl + A , чтобы выбрать файлы, нажмите Ctrl + M , чтобы открыть окно инструмента многократного переименования, и остальное самоочевидно. Если вам все же нужна помощь, нажмите клавишу F1 , чтобы открыть страницу справки для инструмента переименования.

0 голосов
/ 05 января 2019

Ваш вопрос недостаточно конкретен, чтобы мы могли предложить решение, вам действительно нужно предоставить раздел кода, в который вы хотите, чтобы это было интегрировано.

Этот ожидает только один файл, как в вашем вопросе, и этот файл должен быть назван в указанном вами формате, то есть необходимая часть отделена от ненужной части пробелом:

@Set "name=7612372 filename 50x50.jpg"
@Ren "%name%" "%name:* =%"

[Редактировать /]

Я заметил из ваших комментариев, что вы действительно пытались проанализировать несколько файлов, и эти файлы не соответствуют схеме именования, которую вы указали в своем вопросе.

Здесь, следовательно, обновленное потенциальное решение, основанное на этих измененных параметрах.

@For %%A In (*.*) Do @For /F "Tokens=* Delims=0123456789 " %%B In ("%%A") Do @Ren "%%~A" "%%B"

Извинения перед LotPings, который, как я заметил, опубликовал очень похожий метод / решение

0 голосов
/ 05 января 2019

Если формат имени файла будет одинаковым для всех файлов в папке, то вы можете попробовать:

@echo off

for /F "delims=" %%A IN ('dir /b /A-D') do (
    for /F "tokens=2-3" %%B IN ("%%A") do (
        ren "%%~fA" "%%B %%C"
    )
)

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

@echo off
setlocal EnableDelayedExpansion

for /F "delims=" %%A IN ('dir /b /A-D') do (
    set filename=%%A
    for /F "tokens=1" %%B IN ("%%A") do (
        ren "%%~fA" "!filename:%%B =!"
    )
)

, что более точно и правильно переименовывает все файлы , только если они имеют формат, указанный в начале .

  • @echo off отключает вывод команды выключено .
  • setlocal EnableDelayedExpansion включает замедленное расширение . Мы используем это только здесь, так как мы должны обращаться к переменным внутри цикла for, который является блоком кода. Вы должны использовать отложенное расширение всегда внутри этих блоков кода.
  • Теперь мы делаем цикл for, чтобы анализировать вывод (/F) команды dir /b /A-D, в которой перечислены все элементы в текущем рабочем каталоге (%cd%), , исключая каталоги (/A-D).
    • Нам нужно установить здесь переменную с именем файла. Мы могли бы использовать имя переменной цикла (%%A), но у переменных есть преимущество: %var:search=replace% или даже !var:search=replace!, что нам нужно здесь.
    • Теперь мы делаем еще один цикл for для анализа строки (/F): имя файла (%%A). Нам нужен доступ к первому токену, чтобы вычесть его позже. Нам не нужно указывать это здесь, но хорошо бы прояснить это.
      • Теперь мы переименовываем файлы: %%~fA - это полный путь, по которому в настоящее время обрабатывается имя файла, а !filename:%%B =! означает получение filename переменной окружения, поиск строки "%%B " (первая часть имени файла [цифры] и пробел). ) и замените его пустой строкой; на самом деле ничего!
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...