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 

[Script] Выполнение команды для каждого элемента списка
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    Total Commander Forum Index -> Автоматизация Total Commander printer-friendly view
View previous topic :: View next topic  
Author Message
Batya



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

Post (Separately) Posted: Wed Dec 31, 2008 11:13    Post subject: [Script] Выполнение команды для каждого элемента списка Reply with quote

Представляю MultiRun.vbs - выполняет мнократный запуск команды для каждого элемента в файле-списке.
Code:
'=======================================================================================
' Выполнение указанной команды (программы) для каждого элемента файла-списка

' Параметры скрипта:
' 1 - Набор режимов, где каждый режим определяется цифрами по разрядам:
'     1 - обрабатывать каждый список отдельно (0 - умолч.) или синхронно (1),
'     2 - последовательное (0 - умолч.) или параллельное (1) выполнение команд по списку
' 2 и далее - Выполняемая команда (программа) и параметры к ней
' Начало и конец файла-списка определяется заданными ниже символами (набором символов).
'   Команда выполняется для каждого элемента списка, подстановкой этого элемента в
'   местоположение списка.
' В качестве параметра может быть указано текстовое содержимое буфера обмена.
'   Тэг буфера обмена задается в секции скрипта "Изменяемые параметры".
'   Для использования буфера обмена в системе должен быть установлен TCScript.Helper.
' Например, параметры вызова из TC для одновременного фонового извлечения из архивов,
'   пароль к которым находится в буфере обмена, в текущую папку:
'   10 "%ProgramFiles%\WinRar\WinRar.Exe" X -ibck -p### {{%L}} "%P"
'
' Автор  - Batya
' Версия - 1.2
'=======================================================================================
Option Explicit
'================= Изменяемые параметры ================================================
Const ListBegin    = "{{"  'Начало списка
Const ListEnd      = "}}"  'Конец списка
Const ClipboardTag = "###" 'Тэг буфера обмена 
'=======================================================================================
Dim FSO, WSH, Mess, Mode(1), Command, i, L, P, LenListBegin, LenListEnd, Clipboard
Set FSO  = CreateObject("Scripting.FileSystemObject")
Set WSH  = CreateObject("WScript.Shell")

'Задаем массив сообщений
MessDefine
'Проверяем параметры
CheckParams

LenListBegin = Len(ListBegin)
LenListEnd   = Len(ListEnd)

'Выполняем команды по списку
For Each L In SearchList(Command, 0)
  'Тестовая строка - раскомментарить для проверки
  'MsgBox L, vbOKOnly, Mess(5)
  WSH.Run L, 7, (Mode(1) = 0)
Next

'Выход
Quit

'===== Процедуры и функции =============================================================
'Проверка входных параметров
Sub CheckParams
  Dim k, m, lP, n
  With WScript
    If .Arguments.Count = 0 Then
      MsgBox Mess(1), vbCritical + vbOKOnly, Mess(0)
      Quit
    End If
    If .Arguments.Count < 2 Then
      MsgBox Mess(2), vbCritical + vbOKOnly, Mess(0)
      Quit
    End If
    m = .Arguments(0)
    For i = 1 To .Arguments.Count - 1
      lP = WSH.ExpandEnvironmentStrings(.Arguments(i))
      If InStr(lP, " ") > 0 Then lP = """" & lP & """"
      Command = Command & " " & lP
    Next
    Command = Mid(Command, 2)
  End With
  n = UBound(Mode) + 1
  m = Right(String(n, "0") & m, n)
  For i = 0 To n - 1
    k = Left(Right(m, i + 1), 1) 'Берем очередной разряд
    'Проверяем правильность задания каждого режима
    Select Case i
      Case 0
        If IsNumeric(k) Then k = CInt(k)
        If (k=0) Or (k=1) Then Mode(i) = k
      Case 1
        If IsNumeric(k) Then k = CInt(k)
        If (k=0) Or (k=1) Then Mode(i) = k
    End Select
  Next
End Sub

'Поиск в строке тэгов файлов-списков и формирование массива элементов
Function SearchList(pStr, byVal pDepth)
  Dim lList, lL, lPos1, lPos2, lStr, lBegin, lEnd, lList1, lL1, lList2, k, m
  If UCase(ListBegin) = UCase(ListEnd) Then
    'Ищем начало списка
    lPos1 = InStr(1, pStr, ListBegin, vbTextCompare)
    If lPos1 = 0 Then
      SearchList = Array(SearchClipboard(pStr))
      Exit Function
    End If
    'Ищем конец списка
    lPos2 = InStr(lPos1 + LenListBegin, pStr, ListEnd, vbTextCompare)
    If lPos2 = 0 Then
      SearchList = Array(SearchClipboard(pStr))
      Exit Function
    End If
  Else
    'Ищем конец списка
    lPos2 = InStr(1, pStr, ListEnd, vbTextCompare)
    If lPos2 = 0 Then
      SearchList = Array(SearchClipboard(pStr))
      Exit Function
    End If
    'Ищем начало списка
    lPos1 = InStrRev(pStr, ListBegin, lPos2 - 1, vbTextCompare)
    If lPos1 = 0 Then
      SearchList = Array(SearchClipboard(pStr))
      Exit Function
    End If
  End If
  'Файл-список
  lList = Mid(pStr, lPos1 + LenListBegin, lPos2 - lPos1 - LenListBegin)
  'Если файла-списка не существует, выходим
  If Not FSO.FileExists(lList) Then
    MsgBox Mess(3) & " """ & lList & """ " & Mess(4),_
           vbCritical + vbOKOnly, Mess(0)
    Quit
  End If
  'Начало и конец командной строки
  lBegin = Left(pStr, lPos1 - 1)
  lEnd   = Mid(pStr, lPos2 + LenListBegin)
  'Перебираем список
  lList2 = Split(FSO.OpenTextFile(lList, 1, False, -2).ReadAll, vbNewLine)
  m = pDepth
  If pDepth = 0 Then
    pDepth = UBound(lList2)
    m = 0
  End If
  For k = m To pDepth
    lL = lList2(k)
    If lL = "" Then Exit For
    lL = WSH.ExpandEnvironmentStrings(lL)
    If InStr(lL, " ") > 0 Then lL = """" & lL & """"
    'Формируем выходной список в зависимости от режима
    Select Case Mode(0)
      Case 0
        'Рекурсивный поиск списка
        lList1 = SearchList(lBegin & lL & lEnd, 0)
        For Each lL1 In lList1
          lStr = lStr & vbNewLine & lL1
        Next
      Case 1
        'Рекурсивный поиск списка
        lList1 = SearchList(lBegin & lL & lEnd, k)
        lStr   = lStr & vbNewLine & lList1(0)
    End Select
  Next
  SearchList = Split(SearchClipboard(Mid(lStr, Len(vbNewLine) + 1)), vbNewLine)
End Function

'Подстановка текстового значения из буфера обмена
Function SearchClipboard(pStr)
  If UBound(Filter(Array(pStr), ClipboardTag)) >= 0 Then
    SearchClipboard = Replace(pStr, ClipboardTag, GetClipboard)
  Else
    SearchClipboard = pStr
  End If
End Function

'Содержимое буфера обмена
Function GetClipboard()
  If IsEmpty(Clipboard) Then
    GetClipboard = CreateObject("TCScript.Helper").GetTextFromClip
  Else
    GetClipboard = Clipboard
  End If
End Function

'Описание сообщений
Sub MessDefine
  Set Mess = CreateObject("Scripting.Dictionary")
  With Mess
    .Add 0,  "Выполнение программы для списка"
    .Add 1,  "Не указаны параметры!"
    .Add 2,  "Не указана выполняемая команда!"
    .Add 3,  "Файл-список"
    .Add 4,  "не существует!"
    .Add 5,  "Тест командной строки"
  End With
End Sub

'Выход
Sub Quit
  Set Mess = Nothing
  Set WSH  = Nothing
  Set FSO  = Nothing
  WScript.Quit
End Sub

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


Last edited by Batya on Sat Feb 06, 2010 19:55; edited 6 times in total
Back to top
View user's profile Send private message
Batya



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

Post (Separately) Posted: Wed Dec 31, 2008 12:25    Post subject: Reply with quote

Скрипт поправлен.
Теперь будет корректно отрабатывать конструкция вида "<<<<{файл-список}>>>>", означающая, что файл-список содержит другие файлы-списки.

В планах:
- Выполнение нескольких раздельных команд (например, сначала распаковка каждого из списка архивов, потом удаление архивов).
- Возможность задания диапазона обработки списка (например, при занесении песен в плей-лист Winamp-а для первого элемента надо толкнуть команду без параметров, а для остальных с параметром "/add").

Другие предложения есть?
_________________
Нет, я не сплю. Я просто медленно моргаю.
Back to top
View user's profile Send private message
Batya



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

Post (Separately) Posted: Mon Mar 02, 2009 18:32    Post subject: Reply with quote

Исправлен исходный скрипт - добавлена возможность использования в параметрах буфера обмена. Для использования буфера необходимо, чтобы был усталовлен Script Helper.
_________________
Нет, я не сплю. Я просто медленно моргаю.
Back to top
View user's profile Send private message
VadiMGP



Joined: 21 Mar 2007
Posts: 1624

Post (Separately) Posted: Sat Oct 10, 2009 18:39    Post subject: Reply with quote

Попробовал использовать этот скрипт.
Сделал кнопку
Code:
TOTALCMD#BAR#DATA
E:\Downloads\Рапида\house\mrun.vbs
0 "%ProgramFiles%\WinRar\WinRar.Exe" X -ibck <<%L>> "%T"
D:\WINDOWS\System32\WScript.exe
mrun
E:\Downloads\Рапида\house\

-1

Вылетает с ошибкой
Code:
---------------------------
Windows Script Host
---------------------------
Script:   E:\Downloads\Рапида\house\mrun.vbs
Line:   44
Char:   3
Error:   The system cannot find the file specified.
Code:   80070002
Source:    (null)
В чем может быть причина? Ось - Win XP SP2, TC 7.50a

Кстати, заодно ещё вопрос - Если использовать Вместо %L параметр %WL или %UL, то скрипт это примет?
Back to top
View user's profile Send private message
Batya



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

Post (Separately) Posted: Mon Oct 12, 2009 09:44    Post subject: Reply with quote

VadiMGP wrote:
В чем может быть причина?
"%ProgramFiles%" в строке "Параметры" надо обрамлять двойными процентами - "%%ProgramFiles%%" - фишка TC.

VadiMGP wrote:
Если использовать Вместо %L параметр %WL или %UL, то скрипт это примет?
Пока не примет, но %WL могу прикрутить. %UL прикрутить, видимо, не получится.
_________________
Нет, я не сплю. Я просто медленно моргаю.
Back to top
View user's profile Send private message
VadiMGP



Joined: 21 Mar 2007
Posts: 1624

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

Batya wrote:
%ProgramFiles%" в строке "Параметры" надо обрамлять двойными процентами
Вот ведь позор на мою седую голову - сам сколько раз юзерам TCMenu это талдычил. Smile Спасибо, заработало.

Насчет параметров. %UL - бог с ним, а вот %WL действительно хотелось бы.
Back to top
View user's profile Send private message
Batya



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

Post (Separately) Posted: Mon Oct 12, 2009 13:30    Post subject: Reply with quote

VadiMGP wrote:
%WL действительно хотелось бы
Поправил. Должно работать как с %L, так и %WL.
Чтоб весь скрипт не копировать, можно поменять вызов OpenTextFile:
Code:
FSO.OpenTextFile(lList, 1, False, -2)


VadiMGP
P.S. А чем не нравится аутентичное название файла "MultiRun.vbs"?
_________________
Нет, я не сплю. Я просто медленно моргаю.
Back to top
View user's profile Send private message
VadiMGP



Joined: 21 Mar 2007
Posts: 1624

Post (Separately) Posted: Mon Oct 12, 2009 13:49    Post subject: Reply with quote

Batya wrote:
А чем не нравится аутентичное название файла "MultiRun.vbs"?
Я даже не сразу сообразил о чем ты говоришь. Smile Вполне нравится. Просто я начал писать батник mrun.bat. А потом вспомнил, что видел тут скрипт ну и машинально сохранил в mrun.vbs.
Back to top
View user's profile Send private message
Batya



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

Post (Separately) Posted: Sat Nov 14, 2009 12:15    Post subject: Reply with quote

Из другой темы:
Rodny wrote:
Напиши, пожалуйста, подробнее про набор режимов.

Набор режимов - это несколько цифр, которые, в зависимости от их знакоместа определяют варианты работы скрипта. Под знакоместом я понимаю место цифры в числе. Например, в числе 345 в первом разряде (количество единиц) стоит 5, во втором (количество десятков) - 4, в третьем (количество сотен) - 3.
Т.о. набор режимов скрипта - это число, где
- цифра в первом разряде определяет режим работы для нескольких списков в команде - обрабатывать каждый список отдельно (0) или синхронно (1) - значение параметра не играет никой роли, если в применяемой команде используется только один список;
- цифра во втором разряде определяет порядок обработки итогового списка команд - последовательно, т.е. друг за другом, с ожиданием окончания работы предыдущей команды, - (0); или параллельно, т.е. все команды выполнятюся одновременно, без ожидания окончания работы предыдущей, - (1).

P.S. Надеюсь, объяснил не заморочено. Так понятно?
_________________
Нет, я не сплю. Я просто медленно моргаю.
Back to top
View user's profile Send private message
Rodny



Joined: 24 Jan 2007
Posts: 949
Location: Могилёв, Беларусь

Post (Separately) Posted: Sat Nov 14, 2009 18:36    Post subject: Reply with quote

Batya
Спасибо, я не обратил внимание на упоминание о разрядах
/me ушёл посыпать голову пеплом: математик, блин, по образованию Sad

Про несколько списков, имеется в виду "<<<<{файл-список}>>>>"?
Back to top
View user's profile Send private message
Batya



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

Post (Separately) Posted: Sat Nov 14, 2009 22:11    Post subject: Reply with quote

Rodny wrote:
Про несколько списков, имеется в виду "<<<<{файл-список}>>>>"?

Нет. Имеются в виду конструкции вида "<<{файл-список 1}>> <<{файл-список 2}>>".
Для таких конструкций если в первом разряде 0, то количество строк списков должно быть одинаковым, и команды будут выполнятся синхронно для строк с одинаковым номером из каждого списка. Если же в первом разряде стоит 1, то количество строк в файлах-списках может быть разным, и выполняться команды будут по строчкам - каждая строка из одного списка с каждой строкой из другого списка.
_________________
Нет, я не сплю. Я просто медленно моргаю.
Back to top
View user's profile Send private message
Rodny



Joined: 24 Jan 2007
Posts: 949
Location: Могилёв, Беларусь

Post (Separately) Posted: Sat Nov 14, 2009 22:50    Post subject: Reply with quote

Теперь понял, спасибо. Это ж какой функционал можно на одну кнопку повесить...
Back to top
View user's profile Send private message
Batya



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

Post (Separately) Posted: Sat Feb 06, 2010 19:54    Post subject: Reply with quote

Из-за невозможности в консоли для собственных нужд использовать символы "<" и ">" поменял значения по умолчанию для набора символов начала и конца списка:
Code:
Const ListBegin    = "{{"  'Начало списка
Const ListEnd      = "}}"  'Конец списка

_________________
Нет, я не сплю. Я просто медленно моргаю.
Back to top
View user's profile Send private message
Dimsok



Joined: 17 Aug 2014
Posts: 578

Post (Separately) Posted: Thu Oct 30, 2014 10:19    Post subject: Reply with quote

А чтоб имена файлов без путей были - никак?
Back to top
View user's profile Send private message
Flasher



Joined: 06 Nov 2009
Posts: 12943
Location: Москва

Post (Separately) Posted: Thu Oct 30, 2014 21:11    Post subject: Reply with quote

Dimsok
Напрашивается вопрос - %F вместо %L пробовал?
_________________
Автору сборки TC Image (Andrey_A) настоятельно рекомендуется не распространять на иных ресурсах любую предоставленную мной где-либо техническую информацию по автоматизации и оптимизации в работе с ТС и системой.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Total Commander Forum Index -> Автоматизация Total Commander All times are GMT + 4 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
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