Что нового

Автоматизация переименовать список номерных файлов в обратном порядке

Tosyk

Новичок
Сообщения
206
Репутация
0
приветствую, у меня есть список файлов

image_HD0.jpg
image_HD1.jpg
image_HD2.jpg
...
image_HD7.jpg

мне нужно переименовать их в

image_HD7.jpg
image_HD6.jpg
image_HD5.jpg
...
image_HD0.jpg

как это можно сделать?
 

IMStrelcov

CTPEJIbLLOB
Сообщения
259
Репутация
66
Код:
$aList = FileRead('ListFileName.txt')
$aList = StringRegExpReplace($aList, '(?imsx)([\v]+\z|\A[\v]+)', '')
$aList = StringRegExpReplace($aList, '(?imsx)([\v]+)', @CRLF)
$aList = StringSplit($aList, @CRLF, 1)
Global $iBegin = 1, $iEnd = $aList[0]

While ($iBegin <= $iEnd)
   If $aList[$iBegin] <> $aList[$iEnd] Then
      $sBegin = @YEAR&@MON&@MDAY&@HOUR&@MIN&@SEC&@MSEC&'.Begin'
      $sEnd = @YEAR&@MON&@MDAY&@HOUR&@MIN&@SEC&@MSEC&'.End'
      FileMove($aList[$iBegin], $aList[$iBegin] & $sBegin, 9)
      If @error Then
         ConsoleWrite('Error Rename: ' & $aList[$iBegin]&@CRLF & 'To: ' & $aList[$iEnd] & @CRLF&@CRLF)
         ExitLoop
      EndIf
      FileMove($aList[$iEnd], $aList[$iEnd] & $sEnd, 9)
      If @error Then
         FileMove($aList[$iBegin] & $sBegin, $aList[$iBegin], 9)
         ConsoleWrite('Error Rename: ' & $aList[$iBegin]&@CRLF & 'To: ' & $aList[$iEnd] & @CRLF&@CRLF)
         ExitLoop
      EndIf
      FileMove($aList[$iBegin] & $sBegin, $aList[$iEnd], 9)
      FileMove($aList[$iEnd] & $sEnd, $aList[$iBegin], 9)
   EndIf
   $iBegin += 1
   $iEnd -= 1
WEnd
 
Автор
Tosyk

Tosyk

Новичок
Сообщения
206
Репутация
0
@IMStrelcov спасибо! можете пояснить его работу? не смог заставить его переименовывать файлы
а если я выделяю эти файлы в папке и перетягиваю на скрипт? не через $CmdLine[0]
Сообщение автоматически объединено:

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

Код:
(
    for /f "delims=*LOD" %%i in ('dir /b *_LOD0.sem') do (
        ren "%%~iLOD0.sem" "%%~iLOD7.sem_tmp" && TIMEOUT /T 0.2 /nobreak
        ren "%%~iLOD1.sem" "%%~iLOD6.sem_tmp" && TIMEOUT /T 0.2 /nobreak
        ren "%%~iLOD2.sem" "%%~iLOD5.sem_tmp" && TIMEOUT /T 0.2 /nobreak
        ren "%%~iLOD3.sem" "%%~iLOD4.sem_tmp" && TIMEOUT /T 0.2 /nobreak
        ren "%%~iLOD4.sem" "%%~iLOD3.sem_tmp" && TIMEOUT /T 0.2 /nobreak
        ren "%%~iLOD5.sem" "%%~iLOD2.sem_tmp" && TIMEOUT /T 0.2 /nobreak
        ren "%%~iLOD6.sem" "%%~iLOD1.sem_tmp" && TIMEOUT /T 0.2 /nobreak
        ren "%%~iLOD7.sem" "%%~iLOD0.sem_tmp" && TIMEOUT /T 0.2 /nobreak
        ren "*.sem_tmp" "*.sem")    
)

а список файлов выглядит вот таким образом:
1606549291987.png

но этот скрипт не учитывает того что файлов может быть 3 или 300. я подумал, что автоит сможет с этим лучше справиться.
 
Последнее редактирование:

IMStrelcov

CTPEJIbLLOB
Сообщения
259
Репутация
66
Код:
;загружаем список файлов, которые нужно переименовать, из файла
$aList = FileRead('ListFileName.txt')
;обрабатываем список для избежания ошибок
$aList = StringRegExpReplace($aList, '(?imsx)([\v]+\z|\A[\v]+)', '')
$aList = StringRegExpReplace($aList, '(?imsx)([\v]+)', @CRLF)
$aList = StringSplit($aList, @CRLF, 1)
Global $iBegin = 1, $iEnd = $aList[0]

;перебираем список беря первый и последний и их имена меняим
;потом второй и предпоследний и т.д.
While ($iBegin <= $iEnd)
    ;проверяем разные ли имена у двух файлов
   If $aList[$iBegin] <> $aList[$iEnd] Then
      ;временные имена
      $sBegin = @YEAR&@MON&@MDAY&@HOUR&@MIN&@SEC&@MSEC&'.Begin'
      $sEnd = @YEAR&@MON&@MDAY&@HOUR&@MIN&@SEC&@MSEC&'.End'
      FileMove($aList[$iBegin], $aList[$iBegin] & $sBegin, 9)
      If @error Then
         ConsoleWrite('Error Rename: ' & $aList[$iBegin]&@CRLF & 'To: ' & $aList[$iEnd] & @CRLF&@CRLF)
         ExitLoop
      EndIf
      FileMove($aList[$iEnd], $aList[$iEnd] & $sEnd, 9)
      If @error Then
         FileMove($aList[$iBegin] & $sBegin, $aList[$iBegin], 9)
         ConsoleWrite('Error Rename: ' & $aList[$iBegin]&@CRLF & 'To: ' & $aList[$iEnd] & @CRLF&@CRLF)
         ExitLoop
      EndIf
      FileMove($aList[$iBegin] & $sBegin, $aList[$iEnd], 9)
      FileMove($aList[$iEnd] & $sEnd, $aList[$iBegin], 9)
   EndIf
   $iBegin += 1
   $iEnd -= 1
WEnd

а если я выделяю эти файлы в папке и перетягиваю на скрипт? не через $CmdLine[0]
При перетаскивании файлов на готовый скрипт (EXE), скрипт будет запускаться для каждого файла и папки отдельно, то есть всегда будет получаться что файл для переименования в списке один, а не два и более, как требуется. И это я не только о своем коде, а в общем. Что бы обойти это, используйте
FileFindFirstFile() для создания списка файлов, которые требуется переименовать, и на скрипт перетаскивайте папку где лежат файлы. В моем примере список берется из отдельного ранее подготовленного файла, для примера. То есть вам остается реализовать создание списка файлов.
Пробуйте такой вариант:
Код:
;скомпилируйте скрипт и на EXE перетяните папку с файлами
;подпапки не учитываются

;учитывайте, что скрипт не выводит никаких сообщений об успехе или ошибке переименовавния
;если скрипт не сможет переименовать, к примеру 1-й и последний файл, то он вернет им первоначальные имена
;то есть 1 переименовали в 1tmp
;а 6 в 6tmp не удалось
;тогда бывший 1, теперь 1tmp, переименует назад в 1
;если удалось и 6 переименовать в 6tmp
;тогда переименовываем дальше
;6tmp в 1, а 1tmp в 6 и т.д. с другими файлами

;перебираем список комманд запуска, ища в нем папку, в которой лежат файлы
For $i1 = 1 To $CmdLine[0]
   ;если это папка, то создаем список файлов лежащих в ней, не папок
   If StringInStr(FileGetAttrib($CmdLine[$i1]), 'D') Then
      $vList = ''
      $hList = FileFindFirstFile($CmdLine[$i1] & '\*.*')
      While 1
         $sFile = FileFindNextFile($hList)
         If @error Then ExitLoop
         If Not StringInStr(FileGetAttrib($CmdLine[$i1] & '\' & $sFile), 'D') Then $vList &= $sFile & @CRLF
      WEnd
      FileClose($hList)
      $vList = StringRegExpReplace($vList, '(?imsx)([\v]+\z)', '')
      $vList = StringSplit($vList, @CRLF, 1)
      ;переименовываем файлы беря 1-й файл в списке и последний
      ;потом 2-й и предпоследний и т.д.
      $iBegin = 1
      $iEnd = $vList[0]
      While ($iBegin <= $iEnd)
         If $vList[$iBegin] <> $vList[$iEnd] Then
            ;эти две переменные для временного именования файла, требуется чтобы не перезаписать существующие файлы
            $sBegin = @YEAR&@MON&@MDAY&@HOUR&@MIN&@SEC&@MSEC&'.Begin'
            $sEnd = @YEAR&@MON&@MDAY&@HOUR&@MIN&@SEC&@MSEC&'.End'
            FileMove($CmdLine[$i1] & '\' & $vList[$iBegin], $CmdLine[$i1] & '\' & $vList[$iBegin] & $sBegin, 9)
            If @error Then ExitLoop
            FileMove($CmdLine[$i1] & '\' & $vList[$iEnd], $CmdLine[$i1] & '\' & $vList[$iEnd] & $sEnd, 9)
            If @error Then
               FileMove($CmdLine[$i1] & '\' & $vList[$iBegin] & $sBegin, $CmdLine[$i1] & '\' & $vList[$iBegin], 9)
               ExitLoop
            EndIf
            FileMove($CmdLine[$i1] & '\' & $vList[$iBegin] & $sBegin, $CmdLine[$i1] & '\' & $vList[$iEnd], 9)
            FileMove($CmdLine[$i1] & '\' & $vList[$iEnd] & $sEnd, $CmdLine[$i1] & '\' & $vList[$iBegin], 9)
         EndIf
         $iBegin += 1
         $iEnd -= 1
      WEnd
   EndIf
Next

MsgBox(0,0,'Срипт окончил работу')


И учтите что список может быть составлен не правильно, так как у системы или AutoIt-а свои критерии сортировки файлов по имени, из-за чего может быть что файл который должен быть в начале списка, окажется в середине списка, и тогда произойдет не тот результат который вам нужен, вот почему я для первого примера брал список файлов из заранее готового файла.
 
Последнее редактирование:
Верх