Script Request

Обсуждение вопросов автоматизации Total Commander с помощью сторонних программ и скриптовых технологий.

Модераторы: Avada, CaptainFlint, Nik, d-view, Моторокер

Аватара пользователя
Batya
Сообщения: 2236
Зарегистрирован: Ср дек 15, 2004 09:51
Откуда: Москва, Россия

Сообщение Batya »

gumanok писал(а):Теперь нужно запихать файл на несколько уровней поглубже.
vbs:

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

'==============================================================================
' Создание дерева папок согласно разделителя в имени файла.
' В именах создаваемых папок первый символ делается заглавным.
' Например,если разделитель "_", а имя файла "abc_de_fghi_jk.ext", то
'   будет создано "Abc\De\Fghi\jk.ext".

' Параметры:
' {список файлов} [{целевая папка} [{режим} [{разделители}]]]
' где {режим} по разрядам может принимать значения:
'   1-й разряд цифр:
'     1 - копирование (по умолчанию},
'     2 - перемещение;
'   2-й разряд цифр:
'     1 - переименовывать файл (по умолчанию},
'     2 - не переименовывать.
' Если не указана {целевая папка}, то используется папка файла.
' Можно указать несколько разделителей, перечислив их через символ ""

' Пример параметров вызова из TC:
' %L "%T" 22 "_\-\test"

' Автор - Batya
'==============================================================================
Option Explicit
'================= Изменяемые параметры =======================================
Const DefaultMode       = 11    'Режим по умолчанию
Const UpperCaseMode     = True  'Изменять ли регистр первого символа имени папки
Const DefaultSeparators = "_\-" 'Разделители по умолчанию
'==============================================================================
Dim FSO, FileList, TargetDir, Mode, Separators, Mess, WSH, F, NameArr, r, i, S
Dim Path, Name, FullPath

SetMess
Set WSH = CreateObject("WScript.Shell")
Set FSO = CreateObject("Scripting.FileSystemObject")
CheckParam
For Each F In Split(FSO.OpenTextFile(FileList).ReadAll, vbNewLine)
  If F = "" Then Exit For
  NameArr = FSO.GetBaseName(F)
  For Each S In Separators
    NameArr = Replace(NameArr, S, vbNewLine)
  Next
  NameArr = Split(NameArr, vbNewLine)
  If TargetDir = "" Then
    Path = FSO.GetAbsolutePathName(FSO.GetParentFolderName(F))
  Else
    Path = TargetDir
  End If
  r = UBound(NameArr)
  On Error Resume Next
  For i = 0 To r - 1
    Name = NameArr(i)
    If Name <> "" Then
      If UpperCaseMode Then Name = UCase(Left(Name,1)) & Mid(Name, 2)
      Path = Path & "" & Name
      If Not FSO.FolderExists(Path) Then FSO.CreateFolder Path
      If Err.Number <> 0 Then
        MessBox Mess(5) & vbNewLine & Err.Description, 1
        Err.Clear
        Quit
      End If
    End If
  Next
  If Rank(Mode, 2) = 2 Then NameArr(r) = FSO.GetBaseName(F)
  FullPath = Path & "" & NameArr(r) & "." & FSO.GetExtensionName(F)
  Select Case Rank(Mode, 1)
    Case 1 FSO.CopyFile F, FullPath
    Case 2 FSO.MoveFile F, FullPath
  End Select
  If Err.Number <> 0 Then
    MessBox Mess(5) & vbNewLine & Err.Description, 1
    Err.Clear
    Quit
  End If
  On Error GoTo 0
Next

MessBox Mess(6), 3

Quit

Sub CheckParam
  If WScript.Arguments.Count = 0 Then
    MessBox Mess(1), 1
    Quit
  End If
  FileList = WScript.Arguments(0)
  If Not FSO.FileExists(FileList) Then
    MessBox Mess(2), 1
    Quit
  End If
  If WScript.Arguments.Count > 1 Then
    TargetDir = WScript.Arguments(1)
    If Not TargetDir = "" Then
      TargetDir = GetPath(TargetDir)
      If Not FSO.FolderExists(TargetDir) Then
        MessBox Mess(3), 1
        Quit
      End If
    End If
  Else
    TargetDir = ""
  End If
  If WScript.Arguments.Count > 2 Then
    Mode    = WScript.Arguments(2)
    If Mode = "" Then Mode = DefaultMode
    If IsNumeric(Mode) Then
      Mode = CInt(Mode)
    Else
      MessBox Mess(4), 1
      Quit
    End If
    If Not(Rank(Mode,1) = 1 Or Rank(Mode,1) = 2) Then
      MessBox Mess(4), 1
      Quit
    End If
    If Not(Rank(Mode,2) = 1 Or Rank(Mode,2) = 2) Then
      MessBox Mess(4), 1
      Quit
    End If
  Else
    Mode = DefaultMode
  End If
  If WScript.Arguments.Count > 3 Then
    S = WScript.Arguments(3)
  Else
    S = ""
  End If
  If S = "" Then S = DefaultSeparators
  Separators = Split(S, "")
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,  "Операция завершена."
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 = vbExclamation + vbOKCancel
  End Select
  MessBox = MsgBox(pMess, lIcon, Mess(0))
End Function

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

Function Rank(pNumber, pPosition)
  Rank = Left(Right(pNumber, pPosition), 1)
End Function

Sub Quit
  Set Mess = Nothing
  Set FSO  = Nothing
  Set WSH  = Nothing
  WScript.Quit
End Sub
Добавлено:
- возможность не переименовывать файл;
- возможность задать несколько разделителей;
- несколько разделителей подряд обрабатываются, как один.
Последний раз редактировалось Batya Ср апр 15, 2009 17:23, всего редактировалось 2 раза.
Нет, я не сплю. Я просто медленно моргаю.
gumanok
Сообщения: 8
Зарегистрирован: Вт янв 27, 2009 14:31

Сообщение gumanok »

С ума сойти! Работает, как часы! Спасибо огромное!
Аватара пользователя
Tol!k
Сообщения: 1727
Зарегистрирован: Вт апр 01, 2008 20:02
Откуда: Арзамас

Сообщение Tol!k »

Batya, сделай пожалуйста, чтоб из имени "abc_de_fghi_jk.ext" создавалось "abc_de\abc_de_fghi_jk.ext"

Ну а если можно будет выбрать

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

• "abc_de\abc_de_fghi_jk.ext"
• "abc\abc_de_fghi_jk.ext"
• "abc\de\abc_de_fghi_jk.ext"
• "abc\de\fghi\abc_de_fghi_jk.ext"
будет вообще сказка :roll:
PS
- количество разделителей может оказаться от 1 до 5
- разделитель может оказаться "сдвоенным" abc_de_fghi__jk.ext ,но считать его нужно за один
Аватара пользователя
Batya
Сообщения: 2236
Зарегистрирован: Ср дек 15, 2004 09:51
Откуда: Москва, Россия

Сообщение Batya »

Tol!k
Необходима чёткая формализация задачи.

Правильно ли я понял? ...
1. Нужно задавать возможность оставить имя файла прежним. Делать это передаваемым параметром или константой в скрипте?
2. Нужна возможность задания начального и конечного индекса при обработке имени файла по разделителю? Делать это передаваемыми параметрами или константами в скрипте?
Tol!k писал(а):- количество разделителей может оказаться от 1 до 5
А это мне каким боком надо учесть?
Tol!k писал(а):- разделитель может оказаться "сдвоенным" abc_de_fghi__jk.ext ,но считать его нужно за один
Ну, с этим все понятно.
Нет, я не сплю. Я просто медленно моргаю.
Аватара пользователя
Tol!k
Сообщения: 1727
Зарегистрирован: Вт апр 01, 2008 20:02
Откуда: Арзамас

Сообщение Tol!k »

Batya
1. Оставить имя файла прежним и не заморачиваться. Файлы перемещать.
2. Нужна возможность задания порядкового номера разделителя, который при обработке имени файла будет преобразован в "". Делать это передаваемыми параметром, например так

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

01  для получения      abc_de\abc_de_fghi_jk.ext 
1   для получения         abc\abc_de_fghi_jk.ext 
111 для получения abc\de\fghi\abc_de_fghi_jk.ext
011 для получения abc_de\fghi\abc_de_fghi_jk.ext
PS
Batya писал(а):
Tol!k писал(а):- количество разделителей может оказаться от 1 до 5
А это мне каким боком надо учесть?
Ну, обрабатывать имя "abc_de_fghi.ext" если параметрах задано 111 из пункта №2 так, будто задано 11 (110)
Можно добавить параметр "строгое соответствие", при указании которого совсем не обрабатывать файлы, количество разделителей в которых меньше, чем в маске из пункта №2. Т.е. пропускать файлы "abc_de.ext" и "abc_de_fghi.ext" если указана маска 111
PPS
Разделителем м.б. "_" и "-"
Аватара пользователя
Tol!k
Сообщения: 1727
Зарегистрирован: Вт апр 01, 2008 20:02
Откуда: Арзамас

Сообщение Tol!k »

Up
?
Аватара пользователя
Batya
Сообщения: 2236
Зарегистрирован: Ср дек 15, 2004 09:51
Откуда: Москва, Россия

Сообщение Batya »

Tol!k
Ты не ответил:
Batya писал(а):1. Нужно задавать возможность оставить имя файла прежним. Делать это передаваемым параметром или константой в скрипте?
Нет, я не сплю. Я просто медленно моргаю.
Аватара пользователя
Tol!k
Сообщения: 1727
Зарегистрирован: Вт апр 01, 2008 20:02
Откуда: Арзамас

Сообщение Tol!k »

Batya писал(а):Ты не ответил
Tol!k писал(а):1. Оставить имя файла прежним и не заморачиваться.
Мне вообще не нужно изменять имена файлов. Просто создавать новые папки и перемещать в них файлы с оригинальными именами.
Но если тебе обязательно "нужно задавать возможность оставить имя файла прежним", то лучше это сделать передаваемым параметром.
Аватара пользователя
Batya
Сообщения: 2236
Зарегистрирован: Ср дек 15, 2004 09:51
Откуда: Москва, Россия

Сообщение Batya »

Tol!k писал(а):- разделитель может оказаться "сдвоенным" abc_de_fghi__jk.ext ,но считать его нужно за один
Tol!k писал(а):1. Оставить имя файла прежним и не заморачиваться.
Tol!k писал(а):Разделителем м.б. "_" и "-"
Готово.
Tol!k писал(а):2. Нужна возможность задания порядкового номера разделителя, который при обработке имени файла будет преобразован в "". Делать это передаваемыми параметром
В разработке.
Нет, я не сплю. Я просто медленно моргаю.
universal007
Сообщения: 16
Зарегистрирован: Чт июл 16, 2009 19:28

Сообщение universal007 »

Batya

vbs-скрипт, использующий Script Helper:

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

'=======================================================
' Создание текстового файла с содержимым буфера обмена
'=======================================================

Спасибо Batya всё работает!

Но есть пару вопросов:
Можно так что бы текстовый фал создавался не в той дирректории
откуда запустился сам скрипт а в любой папке на активной панели?
И если можно то было бы не плохо давать динамическое имя файлу 
например по двум первым словам из текста - как в Word ?
Спасибо.
universal007
Аватара пользователя
Вахмурка
Сообщения: 2587
Зарегистрирован: Пн дек 27, 2004 14:47
Откуда: Большая деревня Москва
Контактная информация:

Сообщение Вахмурка »

Batya молодец, спору нет. Но xxcopy это умеет не хуже, причем как "туда", так и "обратно". Называется это flatten subdirectories. Подробности здесь.
Сайт PowerPro+Total Commander
Скрипты PowerPro для Total Commander
* * *
«Не усматривайте злого умысла в том, что вполне объяснимо глупостью» (Р. Хэнлон)
universal007
Сообщения: 16
Зарегистрирован: Чт июл 16, 2009 19:28

Сообщение universal007 »

Вахмурка писал(а):Но xxcopy это умеет не хуже
Спасибо за быстрый ответ но, к сожалению я в англицком не силён.
Если не трудно опишите подробней сам процес.
К тому же скрипт я сделал на выполнение кнопкой из панели TC.
universal007
Аватара пользователя
Вахмурка
Сообщения: 2587
Зарегистрирован: Пн дек 27, 2004 14:47
Откуда: Большая деревня Москва
Контактная информация:

Сообщение Вахмурка »

Ну, во-первых, есть электронные переводчики. Язык там хороший, правда, автор изредка шутит и использует витиеватые гиперболы. Но редко.

Во-вторых, вкратце суть в следующем. Запуская xxcopy с одним(-ими) ключом(-ами), преобразуем файл c:\One\Two.txt (c:\One - это путь) в файл c'One'Two.txt, где путь "зашит" в имени. Другой ключ (или ключи) производят обратный процесс. Проверял - работает. Символ-разделитель задается.

Чтобы понять, достаточно посмотреть пару "командная строка - примеры". Почти все и так ясно.
Сайт PowerPro+Total Commander
Скрипты PowerPro для Total Commander
* * *
«Не усматривайте злого умысла в том, что вполне объяснимо глупостью» (Р. Хэнлон)
Аватара пользователя
Batya
Сообщения: 2236
Зарегистрирован: Ср дек 15, 2004 09:51
Откуда: Москва, Россия

Сообщение Batya »

universal007 писал(а):Можно так что бы текстовый фал создавался не в той дирректории
откуда запустился сам скрипт а в любой папке на активной панели?
Очисти в кнопке "Путь запуска"
universal007 писал(а):И если можно то было бы не плохо давать динамическое имя файлу
например по двум первым словам из текста - как в Word ?
В скрипте после "If Len(Clip) > 0 Then" напиши:

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

FileName = Left(Clip, InStr(Clip, " ") - 1)
Нет, я не сплю. Я просто медленно моргаю.
universal007
Сообщения: 16
Зарегистрирован: Чт июл 16, 2009 19:28

Сообщение universal007 »

Batya писал(а):В скрипте после "If Len(Clip) > 0 Then" напиши:
Спасибо сработало, но теперь у меня создаётся файл с именем по первому слову из текста но без расширения.
Какая команда отвечает за расширение?
И если не трудно - подскажите где поискать описание команд при создании подобных скриптов?
universal007
Ответить