Страница 1 из 1

Замена имен выделенных файлов копией имени исходного файла

Добавлено: Вс сен 08, 2013 15:47
oshizelly
Можно ли сделать скрипт, чтобы скопировать имя исходного файла и заменить им имя целевого файла (или имена нескольких выделенных файлов) в пассивной панели.

В идеале, хотелось бы два варианта: один с заменой только имени, но не расширения, а второй вариант с заменой имени+расширения (естественно, во втором случае целевой файл может быть только один, так как в противном случае первый переименованный будет затёрт последующими).

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

Спасибо!

Добавлено: Вс сен 08, 2013 19:49
Flasher
Я правильно понял, что базовое имя присваивать нескольким файлам, а цельное только одному?
Если да, то что делать в случае выбора файлов с одинаковым расширением? Счётчик?

Добавлено: Вс сен 08, 2013 20:04
oshizelly
Flasher писал(а): Если да, то что делать в случае выбора файлов с одинаковым расширением? Счётчик?
Теоретически предполагается, что юзер не будет выбирать в качестве целевых файлов для этой операции несколько файлов с одинаковым расширением. Но по ошибке может, конечно, выбрать :P
Тогда либо действительно счётчик, либо просто пропускать их, выдавая соответствующее сообщение об ошибке.

Добавлено: Вс сен 08, 2013 20:25
Flasher
oshizelly писал(а):выдавая соответствующее сообщение об ошибке
Зачем?

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

Добавлено: Вс сен 08, 2013 21:08
oshizelly
Flasher
Flasher писал(а):Зачем?
Ну, чтобы привлечь внимание юзера к тому факту, что при выполнении операции возникли конфликты и поэтому на выходе может быть не совсем то (или совсем не то), что ожидалось.
В идеале такое сообщение должны выдаваться после применения счётчика, чтобы после завершения операции юзер при необходимости внес исправления вручную.
Flasher писал(а):активной панелью, как и в случае с атрибутами, будет панель с выбранным списком.
По этому поводу я уже высказывал своё имхо http://forum.wincmd.ru/viewpost.php?p=95372 в теме про присвоение атрибутов. Но раз по-другому не получается...

Добавлено: Вс сен 08, 2013 21:23
Flasher
oshizelly писал(а):и поэтому на выходе может быть не совсем то (или совсем не то), что ожидалось
Юзер и так должен осознавать принцип работы исходя из подсказки. Сообщения несколько тревожат психику. Пропуск при совпадении хуже погоду не сделает.
oshizelly писал(а):Но раз по-другому не получается.
Я там писал, как можно. Но это не оптимальный вариант.

Добавлено: Вс сен 08, 2013 22:12
oshizelly
Flasher
Flasher писал(а):Юзер и так должен осознавать принцип работы исходя из подсказки. Сообщения несколько тревожат психику. Пропуск при совпадении хуже погоду не сделает.
Юзер-то сознаёт принцип. Я ведь написал выше:
"Теоретически предполагается, что юзер не будет выбирать в качестве целевых файлов для этой операции несколько файлов с одинаковым расширением. Но по ошибке может, конечно, выбрать"
Поэтому пусть лучше сообщения о конфликте тревожат неустойчивую психику бедного юзера, чем он пребывает в заблуждении, что всё получилось, как он рассчитывал. А потом он спохватится, что некоторые файлы так и не были переименованы, но будет уже поздно.
Flasher писал(а):Я там писал, как можно.
Да, писал http://forum.wincmd.ru/viewpost.php?p=95373, но только для одного файла. А для нескольких альтернативного решения так и не нашлось, если не считать непонятной для меня ссылки на Helper.
Собственно, это могли бы быть два разных скрипта с немного различными кодом: одна версия для единичного целевого файла (в пассивной панели), а вторая - для нескольких выделенных (в активной панели).

Добавлено: Пн сен 09, 2013 00:10
Flasher
oshizelly писал(а):чем он пребывает в заблуждении, что всё получилось, как он рассчитывал
Суть автоматизации в том, чтобы юзер вообще об этом не думал. Если есть совпавшие элементы, которые были пропущены, то и мыслить об этом не имеет смысла, так как всё и так будет на своих местах.
oshizelly писал(а):если не считать непонятной для меня ссылки на Helper
Это пока единственное, чем я могу реализовать подобный алгоритм.

Сообщения не трогаю. Предлагаю пока потестить, что есть:

Код: Выделить всё

'====================================================================================== 
' Присвоение имени элемента из пассивной панели выбранным элементам в активной

' Условие: путь запуска пустой

' Параметры: 1) %WL; 2) "%T"; 3) "%M"; 4) <полное/базовое имя: 0/1>;
'            5) <при совпадении пропускать/добавлять № счётчика: 0/1>
' Пример:    %WL "%T" "%M" 0 1
'======================================================================================

With WScript.Arguments 
  If .Count = 0 Then WScript.Quit 
  List = .Item(0) : T = .Item(1) : Name = .Item(2) : OBN = .Item(3) : Add = .Item(4)
End With : Const M = 0
Set FSO = CreateObject("Scripting.FileSystemObject")
For Each F in Split(FSO.GetFile(List).OpenAsTextStream(1, -1).ReadAll, vbNewLine)
  If F <> "" Then
    NN = Name
    If FSO.FileExists(F) Then
      If OBN Then
        Ext = FSO.GetExtensionName(F)
        If FSO.FileExists(T & Name) Then NN = FSO.GetBaseName(Name) & "." & Ext Else _
        NN = FSO.GetFileName(Name) & "." & Ext
      End If : If Add Then ReName NN
      If Not FSO.FileExists(NN) Then FSO.GetFile(F).Name = NN
    Else
      If FSO.FileExists(T & NN) Then NN = FSO.GetBaseName(NN)
      If Add Then ReName NN
      If Not FSO.FolderExists(NN) Then FSO.GetFolder(F).Name = FSO.GetFileName(NN)
    End If
  End If
Next : Set FSO = Nothing

Sub Rename(FName)
  FN = FName : n = 0
  Do While FSO.FileExists(FName) Or FSO.FolderExists(FName)
    n = n + 1 : If n < 10^M Then PFix = Right(String(M, "0") & n, M) Else PFix = n
    If FSO.FileExists(FN) Then
    FName = FSO.GetBaseName(FN) & " (" & PFix & ")." & FSO.GetExtensionName(FN)
    Else FName = FSO.GetFileName(FN) & " (" & PFix & ")"
    End If
  Loop
End Sub

Добавлено: Пн сен 09, 2013 14:52
oshizelly
Flasher
Предлагаю пока потестить, что есть:
Попробовал запустить с параметрами, предложенными в качестве примера:

Код: Выделить всё

%WL "%T" "%M" 0 1
а также

Код: Выделить всё

%WL "%T" "%M" 1 1
и

Код: Выделить всё

%WL "%T" "%M" 1 0
В всех трёх случаях выдаётся сообщение об ошибке, что файл уже существует (Line 25, Char 39). Что он имеет в виду? Что исходнрый файл существует в своей папке? Ну, естественно, он существует, тут не поспоришь :shock:
Что-то не так я делаю. Но что?
Как этим вообще пользоваться? :? Мы тут несколько разных вариантов обсуждали: копирование имени на один целевой или на несколько, в той же панели или в другой...

Flasher писал(а):Суть автоматизации в том, чтобы юзер вообще об этом не думал. Если есть совпавшие элементы, которые были пропущены, то и мыслить об этом не имеет смысла, так как всё и так будет на своих местах.
Попробую пояснить ситуацию на упрощённом примере. Допустим, есть папка с 20-30 файлами в разных форматах:
07.09.2013 tramparam.doc
02.09.2013 tramparam.doc
08.09.2013 uguaga.xls
01.09.2013 hrasbum.ppt
03.09.2013 tralala.docx

....

В общем, случайные имена, которые были временно присвоены файлам в ходе работы над проектом. Теперь юзер хочет их переименовать, чтобы в имени файла как-то отражалось содержимое документа. Он использует для этого имя последней редакции файла в другой папке: NASA steals the Moonlight.doc. Отлично, запускаем скрипт, переименовываем файлы в целевой папке. На выходе получаем:
NASA steals the Moonlight.doc
NASA steals the Moonlight.xls
NASA steals the Moonlight.ppt
NASA steals the Moonlight.docx
NASA steals the Moonlight.002.doc
....

То есть, оказалось, что в целевой папке случайно оказалось два файла с одинаковым расширением .doc. Один из них - лишний. Но какой именно?? Посмотреть по времени создания/модификации? Не факт, зависит от алгоритма работы с документами. Это можно было посмотреть по дате в исходном имени, но это имя уже пребывает в раю для погибших имён файлов. А от циферки [02] в этом смысле никакой пользы.
А вот если бы юзера предупредили заранее о совпадении имён, то он мог бы отменить операцию и ещё раз посмотреть, что там за дубликаты и какой из них правильный. Вот как-то так, не знаю, сумел ли достаточно объяснить...

Добавлено: Пн сен 09, 2013 15:15
Flasher
oshizelly писал(а):Как этим вообще пользоваться?
Для начала прочесть его название.
oshizelly писал(а):Один из них - лишний. Но какой именно?
Человек выделяет что-то конкретное, если один лишний, то он должен знать об этом заранее. Почему? Потому что если он не обращает внимание на последовательность в списке, то мало смысла в том, чтобы он узнавал, что обработан файл, который не следовало обрабатывать, поскольку скрипт в цикле будет спотыкаться на следующем расширении, а не разбивать всё на группы и выдавать сообщение.

Добавлено: Пн сен 09, 2013 21:56
oshizelly
Flasher писал(а):Для начала прочесть его название.
Это же читать надо уметь! :lol:
В общем, разобрался, действительно работает, если выделять на активной и копировать имя из пассивной.

И всё-таки нижайшая просьба: нельзя ли сделать дополнительную модификацию скрипта, чтобы он:
1) копировал в обратном направлении из активной в пассивную? Понимаю, что это возможно только для единичного целевого файла, но тем не менее иногда это - именно то, что требуется.
2) при совпадении расширений выделенных целевых файлов выдавал сообщение, давящее на психику юзера. Согласен на любую комбинацию со счётчиком: до переименования, после него или вместо... Лишь бы минимизировать вероятность ошибки из-за невнимательности юзера.

Добавлено: Пн сен 09, 2013 23:04
Flasher
oshizelly писал(а):Понимаю, что это возможно только для единичного целевого файла
С Хелпером можно и для списка.

2) Не очень понял конечную цель. Нужно выдавать предупреждение, что в списке есть файлы с одинаковым расширением (мол, примите меры) или спотыкач на каждом, или переименовывать первый попавшийся, а остальные скидывать в лог?
И что с папками делать? Там то логичен только счётчик.
oshizelly писал(а):комбинацию со счётчиком
В каком смысле "комбинацию"?

Добавлено: Пн сен 09, 2013 23:15
oshizelly
Flasher писал(а):С Хелпером можно и для списка.
Если можно, то хорошо бы сделать...
Нужно выдавать предупреждение, что в списке есть файлы с одинаковым расширением (мол, примите меры)
Да, имел в виду именно это.
а остальные скидывать в лог?
Если можно сохрнаить в логе исходные имена переименованных файлов, то это в любом случае было бы здорово.
И что с папками делать? Там то логичен только счётчик.
С папками - да. Там ведь нет расширений.
В каком смысле "комбинацию"?
"Комбинацию" в том смысле, что использование счётчика не исключает необходимости выдачи предупреждения. Обе опции могут использоваться совместно.

Добавлено: Ср сен 11, 2013 20:52
Flasher
Нашёл таки время.
oshizelly писал(а):Если можно сохрнаить в логе исходные имена переименованных файлов, то это в любом случае было бы здорово.
Я писал про остальные. Судя по тому, что имелось в виду, это уже отпадает. А список выделенного сохранить и так не проблема.
oshizelly писал(а):Обе опции могут использоваться совместно.
Нет, обе опции могут использоваться по отдельности.

[cut="Вот что получилось на скорую руку:"]

Код: Выделить всё

'===================================================================================== 
' Переименовывать имена элементов пассивной панели в имя элемента активной

' Внимание!: используется компонент Script Helper ActiveX for TC

' Параметры: 1) %V;  2) <полное/базовое имя: 0/1>;
'            3) при наличии совпавших расширений в выбранном списке:
'               а) выдавать сообщение:   0
'               б) добавлять № счётчика: 1
' Пример:    %V 0 1
'=====================================================================================

With WScript.Arguments 
  If .Count = 0 Then WScript.Quit 
  File = .Item(0) : OBN = .Item(1) : Add = .Item(2)
End With : Const M = 0
Set FSO  = CreateObject("Scripting.FileSystemObject")
Set Dict = CreateObject("Scripting.Dictionary")
With CreateObject("TCScript.Helper")
  .LockTC True : List = .GetTrgSelectedFiles(1) : .LockTC False
End With : L = vbNewLine

If Add = 0 Then
  S = "" : i = 0
  For Each F in List
    If F <> "" Then
      If FSO.FileExists(F) Then
        Ext = FSO.GetExtensionName(F) : FN = FSO.GetFileName(F)
        If Not Dict.Exists(Ext) Then
          Dict.Add Ext, FN : i = i + 1
        Else
          FF = Dict.Item(Ext) : If InStr(S, FF) = 0 Then S = S & L & FF
          S = S & L & FN
        End If
      End If
    End If
  Next : If S <> "" Then
    MsgBox "В выбранном списке есть файлы с одним расширением:" & L & _
    S, 48, Space(30) & "Вынужденное завершение" : Dict.RemoveAll : Quit
  End If : Dict.RemoveAll
End If

For Each F in List
  If F <> "" Then
    NN = FSO.GetFileName(File) : PF = FSO.GetParentFolderName(F) & ""
    If FSO.FileExists(F) Then
      If OBN Then
        Ext = FSO.GetExtensionName(F)
        If FSO.FileExists(File) Then NN = FSO.GetBaseName(NN) & "." & Ext Else _
        NN = FSO.GetFileName(File) & "." & Ext
      End If : If Add = 1 And Not FSO.FileExists(PF & NN) Then ReName NN
       If Not FSO.FileExists(PF & NN) Then FSO.GetFile(F).Name = NN
    Else
      If FSO.FileExists(File) Then NN = FSO.GetBaseName(NN)
      ReName NN
      If Not FSO.FolderExists(PF & NN) Then FSO.GetFolder(F).Name = FSO.GetFileName(NN)
    End If
  End If
Next : Quit

Sub Rename(FName)
  FNm = FName : n = 0
  Do While FSO.FileExists(FName) Or FSO.FolderExists(FName)
    n = n + 1 : If n < 10^M Then PFix = Right(String(M, "0") & n, M) Else PFix = n
    If FSO.FileExists(FNm) Then
    FName = FSO.GetBaseName(FNm) & " (" & PFix & ")." & FSO.GetExtensionName(FNm)
    Else FName = FSO.GetFileName(FNm) & " (" & PFix & ")"
    End If
  Loop
End Sub : Sub Quit : Set FSO = Nothing : Set Dict = Nothing : WScript.Quit : End Sub
[/cut]Если возникнут баги, прошу в студию.