2016-12-04 5 views
-1

У меня есть файлы, как показано ниже:Как переименовать файлы с частью имени папки?

H: \ 1 \ PICTURES \ некоторые \ реж \ sdir1 [60] 19 \ [0] - [30] 15 [60] - [ 65] - [999] abc.jpg
H: \ 1 \ \ ИЗОБРАЖЕНИЯ некоторые \ DIR \ sdir200 \ ssdir5 [60] 22 \ [0] 20 [30] 15 [60] - [65 ] 22 [999] abcd.jpg
H: \ 1 \ ИЗОБРАЖЕНИЯ \ некоторые \ DIR \ sdir20 [60] 218 \ [0] - [30] 15 [60] - [65] 100 [ 999] 21ade.jpg
Н: \ 1 \ \ ИЗОБРАЖЕНИЯ некоторые \ DIR \ sdir33 [60] 335 \ [0] - [30] 15 [60] - [65] 31 [999] 2ade.jpg
H : \ 1 \ ИЗОБРАЖЕНИЯ \ некоторые \ DIR \ sdir5 [60] 26 \ [0] - [30] 15 [60] - [65] - [999] 1abc4.jpg
H: \ 1 \ \ ИЗОБРАЖЕНИЯ некоторые \ DIR \ sdir8000 [60] 525 \ [0] - [30] 15 [60] - [65] - [999] abc4.jpg
Н: \ 1 \ ИЗОБРАЖЕНИЯ \ some2 \ dir \ sdir7 [61] 12 \ [0] - [30] 15 [61] - [65] - - [999] abc5.jpg
H: \ 1 \ ИЗОБРАЖЕНИЯ \ some2 \ DIR \ sdir33 [61] 25 \ [0] - [30] 15 [61] - [65] - [ 999] ffc5.jpg

Что я хочу переименовать с партией в:

H: \ 1 \ PICTURES \ некоторые \ реж \ sdir1 [60] 19 \ [0] - [ 30] 15 [60] 19 [65] - [999] abc.jpg
H: \ 1 \ PICTURES \ some \ dir \ sdir200 \ ssdir5 [60] 22 \ [0] 20 [30] 15 [60] 22 [65] 22 [ 999] abcd.jpg
H: \ 1 \ PICTURES \ some \ dir \ sdir20 [60] 218 \ [0] - [30] 15 [60] 218 [65] - [999] 21ade.jpg
Н: \ 1 \ \ ИЗОБРАЖЕНИЯ некоторые \ DIR \ sdir33 [60] 335 \ [0] - [30] 15 [60] 335 [65] 31 [999] 2ade.jpg
Н: \ 1 \ PICTURES \ some \ dir \ sdir5 [60] 26 \ [0] - [30] 15 [60] 26 [65] - [999] 1abc4.jpg
H: \ 1 \ PICTURES \ some \ dir \ sdir8000 [60] 525 \ [0] - [30] 15 [60] 525 [65] - [999] abc4.jpg
H: \ 1 \ PICTURES \ some2 \ dir \ sdir7 [61 ] 12 \ [0] - [30] 15 [61] 12 [65] - [999] ab c5.jpg
Н: \ 1 \ ИЗОБРАЖЕНИЯ \ some2 \ DIR \ sdir33 [61] 25 \ [0] - [30] 15 [61] 25 [65] - [999] ffc5.jpg

Последняя часть имени папки, начиная с [, должна стать строкой, которая заменит строку, с которой начинается одно и то же число в новом имени файла.

Таким образом, замена [60] - с [60] 19 в первом примере.

Длина путей, строк и имен файлов является переменной.

Я знаю, что решение использует tokens и delims, но я не узнал, как получить правильные строки во всех случаях.


EDIT 1:

меня это до сих пор:

@ECHO OFF 
SETLOCAL 
setlocal EnableDelayedExpansion 

SET "sourcedir=H:\1\Pictures\some\dir\sdir1 [60]19" 

FOR /f "delims=" %%a IN ( 
'dir /s /b /a-d "%sourcedir%\*" ' 
) DO (

set newstr=%sourcedir:~-2,2% 
ren "%%a" ????"(%newstr%)"???????????????????????????????? 
) 

Вопросы у меня есть:

  1. Файлы будут переименованы, но имеют () вместо 19.

  2. Путь жестко закодирован вместо переменной.
    (Н: \ 1 \ Pictures` + переменная для некоторых \ DIR \ sdir1 [60] 19, some2 \ DIR \ sdir5 [60] 26 ...)

  3. В set newstr=%sourcedir:~-2,2% я установил фиксированные последние 2 позиции от имени пути. Возможно, необходимо иметь 3 позиции, например. [60] 225.

  4. В команде rename я использую ??? вместо переменных, не являясь решением для использования с переменным положением или длиной для элементов.


EDIT 2:

Я решил первый выпуск. set newstr=%sourcedir:~-2,2% не работает.

Так что я изменил

ren "%%a" ????"(%newstr%)"???????????????????????????????? 

в

ren "%%a" ????"%sourcedir:~-2,2%"????????????????????????????????. 

Но как знать, что там должно быть 2 или 3 цифры в %sourcedir%?

+0

[Эта ссылка] (https://blogs.msdn.microsoft.com/ben/2007/03/09/path-manipulation-in-a-batch-file/) может помочь –

ответ

0

Это можно сделать с помощью следующего пакетного кода:

@echo off 
setlocal EnableExtensions EnableDelayedExpansion 

set "ListFile=%TEMP%\FilesNotRenamed.tmp" 
del "%ListFile%" 2>nul 
set "FileCount=0" 

for /F "delims=" %%A in ('dir /A-D /B /S "H:\1\PICTURES\*.jpg" 2^>nul') do (

    set "FileName=%%~nxA" 
    set "FilePath=%%~dpA" 
    set "FilePath=!FilePath:~0,-1!" 

    for /F "delims=" %%B in ("!FilePath!") do (
     for /F "tokens=2* delims=[]" %%C in ("%%~nxB") do (

      set "FileName=!FileName:[%%C]--=[%%C]%%D!" 
      if not exist "%%~dpA!FileName!" (
       ren "%%A" "!FileName!" 
      ) else if not "%%~nxA" == "!FileName!" (
       set /A FileCount+=1 
       echo %%A>>"%ListFile%" 
      ) 

     ) 
    ) 
) 

if exist "%ListFile%" (
    set "PluralS=s" 
    if %FileCount% == 1 set "PluralS=" 
    echo The following %FileCount% file!PluralS! could not be renamed because a 
    echo file with target name exists already in same directory: 
    echo/ 
    type "%ListFile%" 
    del "%ListFile%" 
    echo/ 
    pause 
) 

endlocal 

Самые внешние ДЛЯ работает команда DIR, который выводит из /B (голый формат) и /S (поиск также рекурсивный во всех подкаталогах) все имена файлов * .jpg с полным путем никогда не заключены в двойные кавычки, найденные в каталоге H:\1\PICTURES, и все его подкаталоги игнорируют каталоги, заканчивающиеся случайно, также с .jpg (очень маловероятно, но кто знает).

DIR выходы для примера:

H:\1\PICTURES\some\dir\sdir5 [60]26\[0]--[30]15 [60]--[65]--[999]1abc4.jpg 
H:\1\PICTURES\some\dir\sdir1 [60]19\[0]--[30]15 [60]--[65]--[999]abc.jpg 
H:\1\PICTURES\some\dir\sdir8000 [60]525\[0]--[30]15 [60]--[65]--[999]abc4.jpg 
H:\1\PICTURES\some\dir\sdir20 [60]218\[0]--[30]15 [60]--[65]100[999]21ade.jpg 
H:\1\PICTURES\some\dir\sdir33 [60]335\[0]--[30]15 [60]--[65]31[999]2ade.jpg 
H:\1\PICTURES\some\dir\sdir200\ssdir5 [60]22\[0]20[30]15 [60]--[65]22[999]abcd.jpg 
H:\1\PICTURES\some2\dir\sdir7 [61]12\[0]--[30]15 [61]--[65]--[999]abc5.jpg 
H:\1\PICTURES\some2\dir\sdir33 [61]25\[0]--[30]15 [61]--[65]--[999]ffc5.jpg 
H:\1\PICTURES\some2\dir\sdir33 [61]25\[0]--[30]15 [61]25[65]--[999]ffc5.jpg 

2^>nul приводит перенаправление вывода сообщения об ошибке с помощью DIR к STDERR к устройству NUL, чтобы подавить его, если нет * .jpg файл можно найти вообще. Характер > должны быть экранированы здесь с ^ следует интерпретировать как оператор перенаправления на выполнение команды DIR и уже не на разборе FOR командной строки, которая приведет к выходу из пакетного исполнения из-за синтаксической ошибки.

Этот список имен файлов затем обрабатывается по строкам самым внешним FOR, в соответствии с которым каждому имени файла с путём назначается переменная цикла A. По умолчанию разбиение строки на пробелы/вкладки отключено на delims=.

Имя файла с расширением файла текущего файла присваивается переменной окружения FileName, а путь к файлу присваивается переменной окружения FilePath.

Далее обратная косая черта в конце пути к файлу удаляется из пути к файлу, что важно для следующего ДЛЯ.

переменных окружения определенно/изменено в командном блоке, начиная с первым ( и заканчивая соответствие ) должны быть привязано в одном командном блоке, используя замедленное расширение, так как команда Windows, процессор заменяет все %variable% значения переменного окружения уже на разбор весь командный блок перед его выполнением в первый раз. Это объясняет использование !FileName! и !FilePath! и последние также !PluralS! вместо %FileName% и %FilePath% и %PluralS% в приведенном выше пакете.

Необходимо следующее имя папки, в которой хранится текущий файл. Имя каталога получается с помощью еще одного FOR, который анализирует путь файла, не заканчивающийся обратным слэшем. Строка после последней обратной косой черты в FilePath ссылается на %%~nxB ... имя файла и расширение файла, которое здесь является именем каталога, поскольку строка, обработанная строкой, является файловым путем, заканчивающимся именем папки, а не с именем файла.

В наружных словах %%~nxB для примеров файлов:

sdir5 [60]26 
sdir1 [60]19 
sdir8000 [60]525 
sdir20 [60]218 
sdir33 [60]335 
ssdir5 [60]22 
sdir7 [61]12 
sdir33 [61]25 
sdir33 [61]25 

Самого внутреннего FOR используется, чтобы получить число в квадратных скобках и число после квадратных скобок. Он разбивает имя папки на строки с использованием [ и ] в качестве разделителей.

Для этой задачи первая строка перед первым [ не представляет интереса. Поэтому с tokens=2 вторая строка в квадратных скобках назначается переменной цикла C.Остальная часть имени папки после ] еще не разделяется и присваивается следующей переменной цикла, которая соответствует ASCII table переменной цикла D, указанной в * после tokens=2.

Для примеров файлов %%C (левый ряд) и %%D (правильное число) являются:

60 26 
60 19 
60 525 
60 218 
60 335 
60 22 
61 12 
61 25 
61 25 

Первая команда в самой внутренней для цикла заменяет ALL (и, надеюсь, все имена файлов всегда только один) [первого номера]-- по [первого номера]второго номер в текущем имени файла.

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

Есть две возможности в случае файла с новым именем уже существует:

  1. Текущий файл был переименован уже раньше. Это можно обнаружить, если новое имя файла идентично имени файла для переименования. В этом случае ничего не делается.

  2. В каталоге файла для переименования есть другой файл, у которого есть новое имя файла. В этом случае файл переименовать с пути записывается во временный файл и файл счетчика увеличивается на 1.

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

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

  • del /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • if /?
  • pause /?
  • ren /?
  • set /?
  • setlocal /?
  • type /?

И смотри также статью Microsoft Using command redirection operators.

+0

Но когда я запускаю скрипт , Dosbox появляется и исчезает немедленно, без переименования каких-либо файлов. Кажется, что набор – pkraftw

+0

Я сделал то, что было предложено: я поместил файл под C :, открыл окно командной строки и запустил командный файл, введя его имя с полным путем, заключенным в двойные кавычки. Открылся dosbox, ничего не написанный в нем и застывший. – pkraftw

+0

Этот командный файл не запускает новый командный процесс. Таким образом, имея этот пакетный код, сохраненный в ANSI-файле 'C: \ Temp \ RenameFiles.bat' и запускаемый из открытого окна командной строки' 'C: \ Temp \ RenameFiles.bat' ', вы должны увидеть сообщение об ошибке, если оно не подавлено как сделано с '2> nul' и' 2 ^> nul'. Измените первую строку на '@echo ON' перед сохранением командного файла и запустите его, чтобы увидеть, какие строки обрабатываются при выполнении командного файла. И временно удалите все '2> nul' и' 2 ^> nul', чтобы увидеть все сообщения об ошибках. – Mofi

Смежные вопросы