Total Commander Forum Index Total Commander
Форум поддержки пользователей Total Commander
Сайты: Все о Total Commander | Totalcmd.net | Ghisler.com | RU.TCKB
 
 RulesRules   SearchSearch   FAQFAQ   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

можно ли быстро заменить файлы в дереве каталогов?

 
Post new topic   Reply to topic    Total Commander Forum Index -> Общие вопросы printer-friendly view
View previous topic :: View next topic  
Author Message
nsp



Joined: 02 Dec 2008
Posts: 10

Post (Separately) Posted: Sat Dec 27, 2008 12:39    Post subject: можно ли быстро заменить файлы в дереве каталогов? Reply with quote

Есть сложная ветвистая структура каталогов (сотни папок). В каждом каталоге имеются свои уникальные файлы. Встала задача заменить эти файлы на новые (имена файлов остаются прежними). Проблема в том, что новые файлы находятся в одном месте (в одной папке). И надо их быстро раскидать по своим каталогам с заменой старых файлов. Очень не хочется вручную открывать каждый каталог в дереве и обновлять там файлы. Можно ли это быстро сделать с помощью TC ? Т.е. чтобы после отыскания совпадающих имен производилось раскидывание новых файлов по соответствующим папкам.
Смотрел возможности синхронизации каталогов в TC (7.02). И не увидел там такой возможности.
Back to top
View user's profile Send private message
Avada



Joined: 01 Aug 2008
Posts: 10415
Location: Россия, Саратов

Post (Separately) Posted: Sat Dec 27, 2008 14:13    Post subject: Reply with quote

nsp
Инструмент синхронизации можно использовать только пошагово, последовательно меняя каталог справа и повторно производя сравнение. Проблема, конечно, в определении этих "соответствующих папок". И в том, насколько их много. Можно через инструментарий поиска дубликатов, но это долго. Для начала надо, конечно, найти все эти дубликаты. А затем в каждом блоке самый новый файл надо раскидать по каким-то другим каталогам. И для этого не надо открывать каждый каталог в дереве. В каждом блоке дубликатов для каждого НЕ последнего файла - CTRL+стрелка в сторону другой панели - открыт целевой каталог. Выбрать что надо в панели дубликатов, скопировать в каталог-получатель, подтвержить перезапись. Открыть следующий... И так по всему списку. Конечно, если дублей в каждом блоке штук пять - это ещё терпимо, а если пятьдесят - терпения не хватит.
Можно попробовать функцию копирования по списку (по аналогии с загрузкой по списку), но там нужно возиться с оформлением этого списка (не столько подлежащих копированию файлов, сколько целевых каталогов). Копирование файла из одного каталога в несколько в текущей версии TC не поддерживается. В перспективе - ожидается.
Возможно, что-то можно придумать со скриптами (тут я не специалист).
_________________
Даже самая богатая фантазия
Не представит себе наши безобразия.
Back to top
View user's profile Send private message
nsp



Joined: 02 Dec 2008
Posts: 10

Post (Separately) Posted: Sat Dec 27, 2008 14:19    Post subject: Reply with quote

Спасибо за ответ. Вижу, что "штатного" и быстрого решения моего вопроса в текущей версии TC нет. Жаль, надеялся на какой-нибудь готовый скрипт.
Немного это странно, т.к. думаю, что проблема пакетного обновления большого числа файлов по дереву каталогов встречается не только у меня...
Back to top
View user's profile Send private message
Batya



Joined: 15 Dec 2004
Posts: 2224
Location: Москва, Россия

Post (Separately) Posted: Mon Dec 29, 2008 11:22    Post subject: Reply with quote

nsp
Скрипт сделаю, но уже, наверное, теперь после январских праздников.
Могу забыть, поэтому напомните мне, если к середине января не будет результата.
_________________
Нет, я не сплю. Я просто медленно моргаю.
Back to top
View user's profile Send private message
nsp



Joined: 02 Dec 2008
Posts: 10

Post (Separately) Posted: Mon Dec 29, 2008 11:37    Post subject: Reply with quote

Batya
Спасибо за обнадеживающий ответ. Smile
Когда начнете писать скрипт думаю неизбежно встанет вопрос, что делать, если в дереве (в разных папках) есть одноименные файлы - т.е. в какую папку (или все) заносить новую версию такого файла.
В моем случае проще - одноименных файлов в дереве нет, только уникальные файлы.
Back to top
View user's profile Send private message
Batya



Joined: 15 Dec 2004
Posts: 2224
Location: Москва, Россия

Post (Separately) Posted: Mon Jan 26, 2009 12:18    Post subject: Reply with quote

vbs-скрипт:
Code:
'==============================================================================
' Замена указанными файлами одноименных файлов во всех вложенных папках

' Параметры:
' {папка с исходными файлами} {корневая папка, в которой заменяются файлы}

' Пример параметров вызова из TC:
' "%P" "%T"

' Автор - Batya
'==============================================================================
Option Explicit
'================= Изменяемые параметры =======================================
Const ViewSubFolders = False 'Просматривать ли вложенные папки в исходной папке
'==============================================================================
Dim FSO, FileList, SourceDir, TargetDir, Mess, oSA, WSH, Count

SetMess
Set oSA = CreateObject("Shell.Application")
Set WSH = CreateObject("WScript.Shell")
CheckParam
If MessBox(Mess(10) & vbNewLine & SourceDir & vbNewLine & vbNewLine & _
           Mess(11) & vbNewLine & TargetDir, 4) = vbCancel Then Quit
Count = 0
Set FileList = CreateObject("Scripting.Dictionary")
FillFileList FileList, SourceDir
FilesReplace FileList, TargetDir

MessBox Mess(7) & vbNewLine & vbNewLine & Mess(8) & Count & Mess(9), 3

Quit

Sub CheckParam
  If WScript.Arguments.Count = 0 Then
    MessBox Mess(1), 1
    Quit
  End If
  If WScript.Arguments.Count < 2 Then
    MessBox Mess(2), 1
    Quit
  End If
  SourceDir = WScript.Arguments(0)
  TargetDir = WScript.Arguments(1)
  Set FSO   = CreateObject("Scripting.FileSystemObject")
  If SourceDir = "" Then
    SourceDir = OpenFolder(Mess(5))
  Else
    SourceDir = GetPath(SourceDir)
  End If
  If TargetDir = "" Then
    TargetDir = OpenFolder(Mess(6))
  Else
    TargetDir = GetPath(TargetDir)
  End If
  If Not FSO.FolderExists(SourceDir) Then
    MessBox Mess(3), 1
    Quit
  End If
  If Not FSO.FolderExists(TargetDir) Then
    MessBox Mess(4), 1
    Quit
  End If
End Sub

Sub FillFileList(byRef pFileList, pFolder)
  Dim lF, lFolder
  Set lFolder = FSO.GetFolder(pFolder)
  For Each lF In lFolder.Files
    If Not pFileList.Exists(lF) Then
      pFileList.Add lF.Name, lF.Path
    End If
  Next
  If ViewSubFolders Then
    For Each lF In lFolder.SubFolders
      FillFileList pFileList, lF.Path
    Next
  End If
  Set lFolder = Nothing
End Sub

Sub SetMess
  Set Mess = CreateObject("Scripting.Dictionary")
  Mess.Add 0,  "Замена одноименных файлов"
  Mess.Add 1,  "Не указаны входные параметры!"
  Mess.Add 2,  "Указаны не все входные параметры!"
  Mess.Add 3,  "Исходная папка не существует!"
  Mess.Add 4,  "Целевая папка не существует!"
  Mess.Add 5,  "Укажите исходную папку"
  Mess.Add 6,  "Укажите целевую папку"
  Mess.Add 7,  "Операция завершена."
  Mess.Add 8,  "Заменена произведена для "
  Mess.Add 9,  " файлов."
  Mess.Add 10, "Выполнить замену файлами из папки"
  Mess.Add 11, "файлов в папке"
End Sub

Function MessBox(pMess, pMode)
  Dim lIcon
  Select Case pMode
    Case 1 lIcon = vbCritical    + vbOKOnly
    Case 2 lIcon = vbExclamation + vbOKOnly
    Case 3 lIcon = vbInformation + vbOKOnly
    Case 4 lIcon = vbQuestion    + vbOKCancel
  End Select
  MessBox = MsgBox(pMess, lIcon, Mess(0))
End Function

Sub FilesReplace(pFileList, pFolder)
  Dim lF, lFolder, lAttr
  Set lFolder = FSO.GetFolder(pFolder)
  For Each lF In lFolder.Files
    If pFileList.Exists(lF.Name) Then
      lAttr = lF.Attributes
      lF.Attributes = lF.Attributes And Not 3
      FSO.CopyFile pFileList(lF.Name), lF.Path, True
      Count = Count + 1
      lF.Attributes = lAttr
    End If
  Next
  For Each lF In lFolder.SubFolders
    FilesReplace pFileList, lF.Path
  Next
  Set lFolder = Nothing
End Sub

Function OpenFolder(pTitle)
  Dim oF, lSelect
  Set oF  = oSA.BrowseForFolder(0, pTitle, 16)
  lSelect = Not (TypeName(oF) = "Nothing")
  If lSelect Then
    OpenFolder = oF.Self.Path
  End If
  Set oF  = Nothing
  If Not lSelect Then
    Quit
  End If
End Function

Function GetPath(pPath)
  GetPath = FSO.GetAbsolutePathName(WSH.ExpandEnvironmentStrings(pPath))
End Function

Sub Quit
  Set Mess = Nothing
  Set FSO  = Nothing
  Set oSA  = Nothing
  Set WSH  = Nothing
  WScript.Quit
End Sub

Здесь в скрипте можно по желанию изменить параметр ViewSubFolders, который указывает, брать ли в исходной папке новые файлы в том числе из вложенных подпапок.
_________________
Нет, я не сплю. Я просто медленно моргаю.


Last edited by Batya on Mon Feb 02, 2009 16:19; edited 1 time in total
Back to top
View user's profile Send private message
nsp



Joined: 02 Dec 2008
Posts: 10

Post (Separately) Posted: Mon Jan 26, 2009 18:38    Post subject: Reply with quote

Спасибо за помощь и ответ.
Только вот что с этим скриптом мне делать?
Я не настолько хорошо знаю TC, чтобы уметь туда "подключать" скрипты... Sad

Вообще-то я рассчитывал на появление plugin Smile
Back to top
View user's profile Send private message
Batya



Joined: 15 Dec 2004
Posts: 2224
Location: Москва, Россия

Post (Separately) Posted: Mon Jan 26, 2009 21:11    Post subject: Reply with quote

nsp wrote:
Только вот что с этим скриптом мне делать?

1. В каталоге TC создаешь подкаталог Utils. В Utils создаешь подкаталог WHS.
2. Создаешь обычный текстовый файл с содержимым из раздела "Код" моего предыдущего поста.
3. Сохраняешь этот файл в ранее созданный каталог WHS с именем ReplaceInTree и (обязательно!) расширением vbs.
4. Создаешь кнопку:
Code:
TOTALCMD#BAR#DATA
%COMMANDER_PATH%\Utils\WHS\ReplaceInTree.vbs
"%P" "%T"
%windir%\system32\shell32.dll,87
Замена файлов во вложенных папках


-1

(Выделяешь всё, что в разделе "Код", включая единицу. Прав. кнопка мыши -> Копировать. В TC на панели прав. кнопка мыши -> Вставить. Получается кнопка.)
5. Используешь (перед тем, как научишься, сделай бэкап новых файлов):
- В одной панели TC открываешь папку, в которой лежат новые файлы.
- В другой панели TC открываешь папку, во вложенных папках которой необходимо обновить файлы.
- Нажимаешь кнопку, когда активна панель с новыми файлами. И смотри, не перепутай!
_________________
Нет, я не сплю. Я просто медленно моргаю.
Back to top
View user's profile Send private message
nsp



Joined: 02 Dec 2008
Posts: 10

Post (Separately) Posted: Tue Jan 27, 2009 12:13    Post subject: Reply with quote

Большое спасибо Batya! Laughing

Вроде все работает правильно - меняет файлы с совпадающими именами, не трогает те, которых в обновлении нет, и не добавляет те, которых нет в обновляемых папках.
Проверил это на тестовой примере. Правда он был небольшой (чуть более 100 файлов, раскиданных по 68 папкам). Смущает, что замена на моем ПК (Cel-2.0/512m) работает не быстро - примерно 5-7 секунд. Реально же будет на 1-2 порядка больше файлов. Сколько же время будет идти замена, если файлов будет не 100, а несколько тысяч? Подозреваю, что тормозит Касперский - надо будет его отключать при замене.

Выскажу маленькие пожелания.
Процесс замены файлов идет "в темную", т.е. никакого индикатора процесса (сколько прошло и сколько еще осталось нет). Мне поначалу даже показалось, что компьютер ничего не делает после нажатия кнопки.
И итоговое окошко лишь говорит, что все завершено. Неплохо было бы увидеть итог - сколько же файлов было заменено.
Но и то, что уже есть в принципе годится. Подозреваю, что навесить "сервис" с помощью скрипта наверно будет непросто (если вообще возможно). А писать plugin, если подобная замена-синхронизация нужна только мне одному, вряд ли имеет смысл.
Back to top
View user's profile Send private message
Batya



Joined: 15 Dec 2004
Posts: 2224
Location: Москва, Россия

Post (Separately) Posted: Tue Jan 27, 2009 14:16    Post subject: Reply with quote

nsp wrote:
никакого индикатора процесса

Это сделать не смогу.
Единственный вариант - копировать не средствами ОС, а например, используя killcopy или что-то подобное.
nsp wrote:
Неплохо было бы увидеть итог - сколько же файлов было заменено.

А вот это могу сделать...
Чуть позже напомните мне Wink
_________________
Нет, я не сплю. Я просто медленно моргаю.
Back to top
View user's profile Send private message
nsp



Joined: 02 Dec 2008
Posts: 10

Post (Separately) Posted: Sun Feb 01, 2009 19:15    Post subject: Reply with quote

Не дожидаясь доработки, проверил работу скрипта на практике: целевая папка - более 7000 файлов. Новые файлы находились в 3 разных каталогах (объединять не стал). Было несколько ошибок:
1. Не все файлы заменялись. Оказалось, что это была моя ошибка - некоторые имена не совпадали.
2. Неожиданно некоторые старые файлы затерли новые. Думаю тут тоже была моя ошибка - видимо перед запуском курсор был не в панели новых файлов, а на панели старых. Вышел "побочный" эффект - можно файлами из дерева заменять и файлы в общем каталоге. Возможно будет работать и более сложный случай, когда слева и справа дерево каталогов (не проверял это).
3. Один раз был сбой работы скрипта (что-то про связанные файлы - сообщение не записал, т.к. при повторном запуске ошибки не было).

Вывод - надо быть очень аккуратным при выполнении скрипта - никакой защиты "от дурака" нет. Полезно перед выполнением сделать дубликаты каталогов (именно это меня выручило при ошибке 2).
Пожелание - наглядно отмечать, что скрипт начал выполняться. У меня вышло, что как-то на кнопку нажал дважды, т.к. не был уверен, что скрипт начал выполняться.
Back to top
View user's profile Send private message
Batya



Joined: 15 Dec 2004
Posts: 2224
Location: Москва, Россия

Post (Separately) Posted: Mon Feb 02, 2009 16:18    Post subject: Reply with quote

nsp wrote:
Вывод - надо быть очень аккуратным при выполнении скрипта - никакой защиты "от дурака" нет.

Об этом я уже писал:
Batya wrote:
- Нажимаешь кнопку, когда активна панель с новыми файлами. И смотри, не перепутай!

nsp wrote:
Пожелание - наглядно отмечать, что скрипт начал выполняться.
Сделал.

Исправил пост со скриптом.
_________________
Нет, я не сплю. Я просто медленно моргаю.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Total Commander Forum Index -> Общие вопросы All times are GMT + 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group