Что нового

Массивы Массовое переименование с заменой

BlagoYar

Русь Великая, Очнись! Поднимись с колен Родная!
Сообщения
64
Репутация
-1
В общем решил синхронизировать с mailru cloud-ом свой Total Commander внутри которого софта гигабайт на 100.
Запустил, потом смотрю, а он мне попереименовывал файлы и папки примерно таким образом
bass_aac (Rus conflicted copy 2019-08-31 00 44 41).dll
или папку вот так
AIMP (Rus conflicted copy 2019-08-31 00 44 41)
Я в Commander-е забил по маске в поиске и понял, что вручную не получится (проще будет "выкинуть ноутбук" :smile: )

ПС. В связи с этим просьба помочь скриптом, который переименует все найденные файлы/папки у которых есть такое
(Rus conflicted copy 2019-08-31 00 44 41)
Естественно, дата и время могут быть другими.
И если переименованный файл уже существует, то заменить тем, который был переименован. И желательно, чтобы в конце выдал лог переименованных папок, так как оно не заменит, а сделает слияние (то бишь переместит папку с конфликтом в папку без конфликста; папки уже можно и вручную потом)
 

eam

Новичок
Сообщения
8
Репутация
1
Я ТЗ не совсем понял, но сделал бы так:
сначала получить массив всех файлов, можно с помощью _FileDirListt, или просто dir/s/b > files.txt и потом
Код:
Dim $Ar
_FileReadToArray("files.txt", $Ar)

Потом пройти массив пр строкам, тут же можно выдавать команды типа FileMove, если это то, что надо
 
Автор
BlagoYar

BlagoYar

Русь Великая, Очнись! Поднимись с колен Родная!
Сообщения
64
Репутация
-1
Я ТЗ не совсем понял, но сделал бы так:
Ну вот есть к примеру файл и папка
D:\Total Commander\Punto Switcher\punto.exe
D:\Total Commander\ClipDiary


Далее я запускаю синхронизацию с облаком и если файл и папка не совпадают с тем, что в облаке (то бишь метка по времени или размеру), то программа от облака переименовывает их так
D:\Total Commander\Punto Switcher\punto (Rus conflicted copy 2019-08-31 00 44 41) .exe
D:\Total Commander\ClipDiary (Rus conflicted copy 2019-08-31 00 44 41)

и загружает то, что есть в облаке, но старее версию

И таких файлов и папок очень много.
И часто бывает так, что программа от облака возвращает мне на ПК файл или папку из облака, а то, что на ПК переименовывает так же, с конфликтом.
Соответственно, если я переименую файл или папку в правильное название (без (Rus conflicted copy 2019-08-31 00 44 41) ), то оно просит о замене, потому что файл уже имеется (программа из облака притянула), поэтому нужно заменить файл на тот, что с ПК (то бишь который был с именем (Rus conflicted copy 2019-08-31 00 44 41) ), а не тот, что из облака без конфликта, потому как он старее.

ПС. За идею благодарю, попробую, если других не поступит.
 

eam

Новичок
Сообщения
8
Репутация
1
ТЗ стало понятнее :smile:, я бы сделал так:

Код:
; 1. Получить список переименованных файлов, напр. так: 
; dir/s/b "*(Rus conflicted copy*.*" >files.txt и_FileReadToArray()
;
; или сразу примерно так
$Ar = _FileListToArray("D:\Total Commander", "*(Rus conflicted copy*.*") 

For $i = 1 to UBound($Ar) - 1

; 2. Восстановить первоначальное имя файла
   $s1 = $Ar[$i]
   $s2 = StringMid($s1, 1, StringInStr($s1, "(", -1) - 1) & StringMid($s1, StringInStr($s1, ")", -1) + 1)
; 3. Перезапись
   FileMove ( $s1, $s2, 1)
Next; $i


Правда мне не совсем понятно, что делать с папками (Total Commander не пользуюсь), но думаю будет несложно
 
Автор
BlagoYar

BlagoYar

Русь Великая, Очнись! Поднимись с колен Родная!
Сообщения
64
Репутация
-1
ТЗ стало понятнее :smile:, я бы сделал так:

Правда мне не совсем понятно, что делать с папками (Total Commander не пользуюсь), но думаю будет несложно
БлагоДарю, испытаю.

По папкам - к примеру:
Есть изначально такая папка
D:\Total Commander\ClipDiary
После синхронизации она становится такая
D:\Total Commander\ClipDiary (Rus conflicted copy 2019-08-31 00 44 41)
А с облака закачивается старая версия
D:\Total Commander\ClipDiary
И нужно эту
D:\Total Commander\ClipDiary (Rus conflicted copy 2019-08-31 00 44 41)
Переместить в эту
D:\Total Commander\ClipDiary

То бишь должно получится так
D:\Total Commander\ClipDiary\ClipDiary (Rus conflicted copy 2019-08-31 00 44 41)
А потом из этой
D:\Total Commander\ClipDiary\ClipDiary (Rus conflicted copy 2019-08-31 00 44 41)
Переместить всё содержимое в эту
D:\Total Commander\ClipDiary
с заменой всех файлов

ПС. Почему так заморочено - потому что насколько мне известно, то windows не может переместить сразу содержимое одинаковой папки с заменой
 

eam

Новичок
Сообщения
8
Репутация
1
Если проблема с папками еще актуальна:
Если точно известно, что при синхронизации в папку D:\Total Commander\ClipDiary\ClipDiary (Rus conflicted copy 2019-08-31 00 44 41) попали все те же самые но более актуальные файлы, что и в D:\Total Commander\ClipDiary , то я понимаю задачу так:
1. получить список всех папок с (Rus conflicted copy ... в массив
2. берем из массива имя папки с (Rus conflicted copy -- $var = D:\Total Commander\ClipDiary\ClipDiary (Rus conflicted copy 2019-08-31 00 44 41)
3. удаляем из имени папки (Rus conflicted copy --имя папки стало $var = D:\Total Commander\ClipDiary
4. проверяем, есть ли такая папка ( т. к. более старая )
если есть - удаляем папку D:\Total Commander\ClipDiary и переименовываем папку D:\Total Commander\ClipDiary\ClipDiary (Rus conflicted copy 2019-08-31 00 44 41) в D:\Total Commander\ClipDiary
если нет - просто переименовываем
И дальше в цикле пп. 2-4
Если файлы внутри папок тоже надо переименовать, то
2а. получаем массив имен файлов в папке с помощью _FileListToArray, и точно также обрабатываем все файлы в папке, как я описал выше
 
Автор
BlagoYar

BlagoYar

Русь Великая, Очнись! Поднимись с колен Родная!
Сообщения
64
Репутация
-1
Если проблема с папками еще актуальна:
Да, актуальна.
Да, точно известно, потому что конфликт дописывает исключительно локальным папкам и копирует из облака старую копию
Но папку удалять нельзя, потому что в некоторых случаях, там могут быть несколько нужных файлов. В этом и проблема. Нужно с заменой сделать.
 

eam

Новичок
Сообщения
8
Репутация
1
Если я правильно понял ТЗ, то все выглядит так:
1. На PC есть папка D:\Total Commander\ClipDiary\ с новыми файлами
2. после синхронизации с облаком папка D:\Total Commander\ClipDiary\ с новыми файлами становится
D:\Total Commander\ClipDiary (Rus conflicted copy 2019-08-31 00 44 41), а D:\Total Commander\ClipDiary\ скачивается из облака как D:\Total Commander\ClipDiary\
При этом новые файлы также переименовываются - из punto.exe получается punto (Rus conflicted copy 2019-08-31 00 44 41) .exe

Если новые файлы действительно новее по дате, есть команда robocopy, которая может копировать только более новые файлы. Тогда надо только сначала переименовать новые файлы обратно, как я уже описывал

Сначала получаем список переименованных папок командой из командной строки или bat-файла
dir/s/b/A:D "*(Rus conflicted copy*.*" >folders.txt

потом скрипт

Код:
#include <File.au3>
#include <Array.au3>


Dim $Ar1, $Ar2, $sBatFileName = "a1.bat"

_FileReadToArray("folders.txt", $Ar1); массив = список переименованных папок

For $i = 1 to UBound($Ar1) - 1
  
  $Ar2 = _FileListToArray($Ar[$i], "",  1) ; массив = список файлов в переименованной папке
  For $k = 1 to UBound($Ar2) - 1
     $s1 = $Ar2[$i]
     If StringInStr($s1, "Rus conflicted") Then
         $iBr1 = StringInStr($s1, "Rus conflicted")
         $iBr1 = StringInStr( $s1, "(", 0, -1, $iBr1) 
         $iBr2 = StringInStr( $s1, ")", 0, 1, $iBr1) 
         $s1 = StringMid($s1, 1, $iBr1-1) & StringMid($s1, $iBr2+1)
         ; т. е. в папке D:\Total Commander\ClipDiary (Rus conflicted copy 2019-08-31 00 44 41)
         ; копируем punto(Rus conflicted copy 2019-08-31 00 44 41).exe в punto.exe
         ; а punto(Rus conflicted copy 2019-08-31 00 44 41).exe стираем
         FileCopy($Ar2[$i], $s1)
         FileDelete ($Ar2[$i])
     EndIf
  Next; $k
Next; $i

; теперь в переименованных папках файлы со старыми именами, какие были до переименования, т. е.
; punto(Rus conflicted copy 2019-08-31 00 44 41).exe стал punto.exe
; здесь лучше сгенерировать bat-файл для копирования файлов, я думаю это сработает быстрее, чем из AutoIt
; и надежнее

For $i = 1 to UBound($Ar1) - 1
     $s1 = $Ar1[$i]
     $iBr1 = StringInStr($s1, "Rus conflicted")
     $iBr1 = StringInStr( $s1, "(", 0, -1, $iBr1) 
     $iBr2 = StringInStr( $s1, ")", 0, 1, $iBr1) 
     $s1 = StringMid($s1, 1, $iBr1-1) & StringMid($s1, $iBr2+1) ; восстановленное старое имя папки
     FileWriteLine ($sBatFileName, "ROBOCOPY " & '"' & $Ar1[$i] & '" "'  & $s1 & '"' & " /XO /S"
Next; $i


тестируем кусочек получившегося bat-файла
если на этом месте bat-файл получится правильно, то можно потом, еогда он все скопирует, 2-м скриптом стереть все переименованные папки с уже скопированными из них файлами

Код:
Dim $Ar1
_FileReadToArray("folders.txt", $Ar1); массив = список переименованных папок
For $i = 1 to UBound($Ar1) - 1
   DirRemove ($Ar1[$i]) ; стереть папку из списка переименованных
Next; $i


Удачи !
 
Верх