Как правильно использовать переименование (ren) в Batch - PullRequest
1 голос
/ 28 июня 2019

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

Я использую Windows 10 и получаю доступ к изображениям с флешки (отсюда и короткий путь к файлу). Я попытался собрать весь код в одном цикле for, но когда это не сработало, я попытался использовать пакетные функции, а не кубики. Я видел, что кто-то упоминал в другом потоке, чтобы использовать отложенное расширение, я был бы готов использовать это, если бы кто-то мог дать лучшее объяснение, чем /? команда.

@echo off

REM batch file is placed in top of F drive, same as "images 2017+"

cd "F:\images 2017+"
FOR /R "F:\images 2017+" %%F in (*.jpg) do call :renER "%%~nF" "%%~tF" 
goto :eof
:renER
cd "F:\images 2017+"
pause
echo %1
echo %2

rename %1.jpg %1_%2.jpg
pause
goto :eof

:end

Для каждого файла .jpg в «images 2017+» дата создания этого файла будет указана в конце после пробела.

thisIsMyFile.jpg, сделанный 5-13-2017, станет thisIsMyFile 5-13-2017.jpg

Токовый выход

EDIT:

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

Ответы [ 3 ]

2 голосов
/ 28 июня 2019

Я заметил, что вам нужна только дата, а не время, поэтому вы можете сделать это следующим образом, используя существующий вызов метки. В этом случае также нет необходимости использовать FOR / R, поэтому я буду использовать обычнуюцикл for:

@echo off
FOR %%A IN ("F:\images 2017+\*.jpg") DO (
  CALL :RenER "%%~fA" %%~tA
)
GOTO :eof
:RenER
  PAUSE
  ECHO %1
  ECHO %2
  SET "_tmp=%~2"
  SET "_tmp=%tmp:/=-"
  REN "%~1" "%~n1_%_tmp%%~x1"
  PAUSE
GOTO :eof

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

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

@echo off
FOR %%A IN ("F:\images 2017+\*.jpg") DO (
  FOR /F "Tokens=1-3 Delims=/ " %%a IN ('echo.%%~tA') DO (
    PAUSE
    ECHO.%%~fA
    ECHO.%%~tA
    REN "%%~fA" "%%~nA_%%a-%%b-%%c%%~xA"
    PAUSE
  )
)

это красиво и чисто, и при незначительном редактировании мы можем вставить его непосредственно в CMD Prompt, что еще лучше Это потому, что мы не используем DelayedExpansion, Calling Label или переменные Tempпоэтому, изменив %% s на % s, мы можем затем вставить это непосредственно в строку CMD, что часто более удобно при выполнении таких операций:

Эта многострочнаяпросто вставьте в CMD напрямую:

FOR %%A IN ("F:\images 2017+\*.jpg") DO (
  FOR /F "Tokens=1-3 Delims=/ " %a IN ('echo.%~tA') DO @(
    PAUSE
    ECHO.%~fA
    ECHO.%~tA
    REN "%~fA" "%~nA_%a-%b-%c%~xA"
    PAUSE
  )
)

или одну строку для вставки в CMD, если вы предпочитаете:

FOR %A IN ("F:\images 2017+\*.jpg") DO @( FOR /F "Tokens=1-3 Delims=/ " %a IN ('echo.%~tA') DO @( PAUSE& ECHO.%~fA& ECHO.%~tA& REN "%~fA" "%~nA_%a-%b-%c%~xA"& PAUSE ) )
1 голос
/ 28 июня 2019

не нужно cd никуда.ren принимает полный путь / имя файла для источника - только местом назначения должно быть только имя файла.Так что ... do call :renER "%%~fF" "%%~tF" хорошо (нет необходимости снимать расширение и добавлять его позже).В подпрограмме переформатируйте время в правильную строку и заново соберите имя файла назначения:

@echo off
FOR /R "F:\images 2017+" %%F in (*.jpg) do call :renER "%%~fF" "%%~tF" 
goto :eof
:renER
pause
echo %1
echo %2
set "string=%~2"
set "string=%string::=-%"
set "string=%string:/=-"
ECHO rename "%~1" "%~n1_%string%%~x1"
pause
goto :eof

:end

ПРИМЕЧАНИЕ. Я снял с охраны команду rename.Удалите ECHO после устранения неполадок, если он работает как задумано.

0 голосов
/ 28 июня 2019

@ Ответ Стефана, вероятно, лучший подход. Но если вы хотите изменить каталоги ...

В оболочке Windows есть рабочий диск / том, а на каждом диске / томе - текущая рабочая папка. cd меняет рабочую папку на диске; чтобы изменить рабочую папку на диске (который не является рабочим диском) и , чтобы сделать этот диск рабочим диском, необходимо использовать cd /d, в данном случае cd /d "F:\images 2017+".
(Обычный cd в этом случае меняет рабочую папку на F:\, но если ваша рабочая папка установлена ​​на C: - как я полагаю, так - она ​​не изменится.)

Предполагая, что расширения команд включены, вы также должны иметь возможность использовать pushd и popd. pushd ведет себя как cd /d, но также сохраняет ваше предыдущее местоположение; popd возвращает вас в это предыдущее местоположение. (И IIRC pushd будет принимать UNC-пути.)
Итак, в начале вашего сценария, pushd "F:\images 2017+", а в конце popd.

Я склонен отдавать предпочтение pushd / popd перед cd, потому что вызовы могут быть вложенными. Так что вы можете делать такие вещи, как (предположим, что рабочий каталог C:\Users\IoCalisto):

pushd "F:\images 2017+"
(рабочий каталог теперь F:\images 2017+)

pushd "Z:\images 2015-2016"
(рабочий каталог теперь Z:\images 2015-2016)

popd
(рабочий каталог теперь F:\images 2017+)

popd
(рабочий каталог теперь C:\Users\IoCalisto)

... при таком подходе ваши сценарии будут иметь меньше «побочных эффектов» и будут более модульными или, по крайней мере, модульными.

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