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 

Замена кусков текста в выделенных файлах
Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8, 9  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: 2218
Location: Москва, Россия

Post (Separately) Posted: Tue Oct 05, 2010 13:00    Post subject: Reply with quote

Flasher wrote:
Речь о формировании временных файлов с текстом поиска/замены (в папке %TEMP%, по всей видимости). Или если какой-то более изощрённый способ?

Текст также, как и у Loopback, будет грузиться в память. Вопрос по объёму файла актуален и для того варианта, который собираюсь реализовать я.

Добавлено.
Вообщем-то, тут особо и писать нечего.
Всё в том же скрипте от Volny после строки
Code:
Find_String = InputBox("Введите искомую строку", "Поиск и замена")
добавь
Code:
Find_String = Replace(Find_String, "\n", vbNewLine)

И после строки
Code:
Replace_String = InputBox("Введите строку для замены", "Поиск и замена")
добавь
Code:
Replace_String = Replace(Replace_String, "\n", vbNewLine)

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



Joined: 07 Sep 2009
Posts: 1279

Post (Separately) Posted: Tue Oct 05, 2010 13:10    Post subject: Reply with quote

Flasher
Тут есть два пути: или отказаться от библиотек, заменив константы из них значениями (что не очень удобно), или скомпилировать скрипт не в экзашник, а в байт-код. Получится один файл, с расширением a3x, который можно запускать как обычный au3, но который уже будет включать все необходимые библиотеки. Для этого в утилите Aut2exe нужно выбрать тип для Destination как "Encoded script files".

И кстати, тут я немного поспешил с библиотеками - можно смело оставить только GUIConstantsEx.au3.


Last edited by Loopback on Tue Oct 05, 2010 13:13; edited 1 time in total
Back to top
View user's profile Send private message
Flasher



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

Post (Separately) Posted: Tue Oct 05, 2010 13:12    Post subject: Reply with quote

CaptainFlint wrote:
Я как раз и подразумевал, что программа может обрабатывать лишь по одному файлу за раз, тогда lst2multi и приведёт к многократному вызову утилиты для каждого файла в отдельности.
Скорее всего Вахмурка подразумевал утилиту, где задаётся список либо путь к файлам, и тут вовсе не имелся в виду редактор MDI/SDI, с которым lst2mlt и lst2str умеют работать. Ну а многократный вызов SDI-приложения вообще не вариант..
Back to top
View user's profile Send private message
Flasher



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

Post (Separately) Posted: Tue Oct 05, 2010 13:27    Post subject: Reply with quote

Batya
Понял, сделаю. Спасибо!
Насчёт рекурсии какие там дела?

Loopback wrote:
скомпилировать скрипт не в экзашник, а в байт-код. Получится один файл, с расширением a3x, который можно запускать как обычный au3, но который уже будет включать все необходимые библиотеки
А ведь точно.
Loopback wrote:
И кстати, тут я немного поспешил с библиотеками - можно смело оставить только GUIConstantsEx.au3
Замечательно! Всё свелось к 2 Кб.
Back to top
View user's profile Send private message
Flasher



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

Post (Separately) Posted: Tue Oct 05, 2010 14:07    Post subject: Reply with quote

Loopback
Я вот ещё о чём подумал. Бывает, что надо заменить несколько разных кусков, разбросанных в разных местах кода/текста на один единственный. Вот хотелось бы (если это возможно) разбивать левое окно на заданное в параметрах кол-во частей ( можно ограничить до 6-8 ), в каждое поле которых будет заносится свой кусок текста. Есть такая возможность?
Back to top
View user's profile Send private message
Batya



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

Post (Separately) Posted: Tue Oct 05, 2010 14:23    Post subject: Reply with quote

Flasher wrote:
Насчёт рекурсии какие там дела?

Замени процедуру DoItForThisFile на:
Code:
Sub DoItForThisFile(FilePath)
   If FSO.FileExists(FilePath) Then
     Set F = FSO.OpenTextFile(FilePath, ForReading)
     Buffer = F.ReadAll
     F.Close
   
     Buffer = Replace(CStr(Buffer), Find_String, Replace_String, 1, -1, 1)
     FSO.CopyFile FilePath, FilePath & ".bak"
   
     Set F = FSO.OpenTextFile(FilePath, ForWriting)
     F.Write Buffer
     F.Close
   End If
   If FSO.FolderExists(FilePath) Then DoItForThisFolder(FilePath)
End Sub

Sub DoItForThisFolder(FolderPath)
   For Each F In FSO.GetFolder(FolderPath).SubFolders
     DoItForThisFolder(F)
   Next
   For Each F In FSO.GetFolder(FolderPath).Files
     DoItForThisFile(F)
   Next
End Sub

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



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

Post (Separately) Posted: Tue Oct 05, 2010 14:49    Post subject: Reply with quote

А можно я со своим реквестом (но в рамках темы) влезу? Embarassed

У меня частный случай: два INI в кодировке UTF-8. Можно ли заданную секцию (целиком) из первого файла скопировать во второй, заменив имеющуюся? Можно упростить задачу: в первом файле только эта одна секция.
Пути файлов и названия секций либо в самом скрипте, либо в параметрах кнопки, непринципиально.
Т.е. никакого интерфейса не требуется, в один клик.

P.S. Оно может уже есть, но вроде не припоминаю, ткните тогда носом, если у кого ссылка под рукой.
P.P.S. Поскольку с AutoIt'ом сталкиваться ещё не доводилось, ставить/компилировать несколько напряжно, если можно будет обойтись vbs, это предпочтительнее.
Back to top
View user's profile Send private message
Loopback



Joined: 07 Sep 2009
Posts: 1279

Post (Separately) Posted: Tue Oct 05, 2010 14:59    Post subject: Reply with quote

Flasher
Ну вот примерно так.
Code:

#include <GUIConstantsEx.au3>

If $CmdLine[0] < 1 Then
    MsgBox (0, "", "Недостаточно параметров, должен быть 1.")
    Exit
EndIf

Global $aList  = _TCHLoadFileList($CmdLine[1])
Global $gReplaces = 0, $gMask

$hGUI = GUICreate("Поиск и замена", 563, 260, -1, -1)
$edSrc = GUICtrlCreateEdit("", 8, 72, 265, 145)
$edTrg = GUICtrlCreateEdit("", 288, 72, 265, 145)
$btnOK = GUICtrlCreateButton("OK", 400, 224, 75, 25)
$btnCancel = GUICtrlCreateButton("Отмена", 480, 224, 75, 25)
GUICtrlCreateLabel("Текст для поиска", 8, 54, 94, 17)
GUICtrlCreateLabel("Текст для замены", 288, 54, 98, 17)
$cbCaseSence = GUICtrlCreateCheckbox("Учитывать регистр", 8, 232, 137, 17)
$edMask = GUICtrlCreateInput("*.*", 8, 24, 265, 21)
GUICtrlCreateLabel("Маска файлов", 8, 6, 78, 17)
GUISetState(@SW_SHOW)

If $aList[0] = 0 Then GUICtrlSetState($btnOK, $GUI_DISABLE)

While 1
   $nMsg = GUIGetMsg()
   Switch $nMsg
      Case $GUI_EVENT_CLOSE, $btnCancel
         Exit
        Case $btnOK
            $gMask = _MaskToRegexp(GUICtrlRead($edMask))
            For $i = 1 To $aList[0]
                If StringRight($aList[$i], 1) = "\" Then
                    _DoFolder($aList[$i])
                Else
                    _DoFile($aList[$i])
                EndIf
            Next
            MsgBox (0, "", "Выполнено замен: " & $gReplaces, 0, $hGUI)
            Exit
   EndSwitch
WEnd

Func _DoFolder($sFolder)
    If $sFolder = "" Then Return
    Local $sDirs = ""
    Local $hSearch = FileFindFirstFile($sFolder & "*.*")
    If @error Then Return
    While 1
        $sFile = FileFindNextFile($hSearch)
        If @error Then ExitLoop
        If @extended Then
            $sDirs &= $sFolder & $sFile & "\" & @LF
            ContinueLoop
        EndIf
        _DoFile($sFolder & $sFile)
    Wend
    FileClose($hSearch)
    ; Обработку каталогов приходится делать отдельно,
    ; чтобы не оставлять открытый поисковый хэндл,
    ; их максимально может быть 64
    $aDirs = StringSplit($sDirs, @LF)
    For $i = 1 To $aDirs[0]
        _DoFolder($aDirs[$i])
    Next
EndFunc

Func _DoFile($sFile)
    If StringRegExp($sFile, $gMask) = 0 Then Return
    Local $sSrcText = FileRead($sFile)
    Local $sTrgText = StringReplace($sSrcText, GUICtrlRead($edSrc), GUICtrlRead($edTrg), 0, _
                                    BitAND(GUICtrlRead($cbCaseSence), $GUI_CHECKED))
    If @extended Then
        $gReplaces += @extended
        Local $hFile = FileOpen($sFile, 2)
        FileWrite($hFile, $sTrgText)
        FileClose($hFile)
    EndIf
EndFunc

Func _MaskToRegexp($sMask)
    $sMask = StringRegExpReplace($sMask, "(\\|\.|\+|\^|\(|\)|\[|\]|\{|\}|\$)", "\\\1")
    $sMask = StringReplace($sMask, "?", ".")
    $sMask = StringReplace($sMask, "*", ".+?")
    Return("(?i)^" & $sMask & "$")
EndFunc

Func _TCHLoadFileList($sFileName)
    Local $asList[1] = [0]
    Local $hfList = FileOpen($sFileName, 0)
    While 1
        $sLine = FileReadLine($hfList)
        If @error Then Exitloop
        ReDim $asList[UBound($asList)+1]
        $asList[UBound($asList)-1] = $sLine
    Wend
    FileClose($hfList)
    $asList[0] = UBound($asList)-1
    Return $asList
EndFunc


Flasher wrote:
Я вот ещё о чём подумал. Бывает, что надо заменить несколько разных кусков, разбросанных в разных местах кода/текста на один единственный. Вот хотелось бы (если это возможно) разбивать левое окно на заданное в параметрах кол-во частей ( можно ограничить до 6-8 ), в каждое поле которых будет заносится свой кусок текста. Есть такая возможность?

Да в принципе всё возможно. Только "окно на части" - это как? Тогда уж проще динамически сделать несколько табов с полями ввода. Ну или просто не закрывать окно после выполнения и менять код в первом поле.
Back to top
View user's profile Send private message
Flasher



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

Post (Separately) Posted: Tue Oct 05, 2010 15:03    Post subject: Reply with quote

Batya
Я чего-то ничего не пойму. Ты предлагал сделать самому замену переносов строки на /n? Ведь в скрипте всё осталось по старому по части окон. Если я заношу в буфер кусок текста, то скрипт с учётом неактивности не сможет преобразовать этот кусок в строку, а значит я смогу вставить только первую строчку и то при условии, если она не будет начинаться с переноса, пробела или табуляции, а это очень нехорошо..

Rodny wrote:
Поскольку с AutoIt'ом сталкиваться ещё не доводилось, ставить/компилировать несколько напряжно
Exe-шник первого скрипта устроит?

Loopback wrote:
Да в принципе всё возможно. Только "окно на части" - это как? Тогда уж проще динамически сделать несколько табов с полями ввода. Ну или просто не закрывать окно после выполнения и менять код в первом поле.
"Табов" в каком смысле? Типа вкладок или всё-таки таблицы? Последний вариант самый простой, но хотелось бы сразу вставить все куски и выполнить по одному клику, пусть и за несколько проходов. Smile
Back to top
View user's profile Send private message
Batya



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

Post (Separately) Posted: Tue Oct 05, 2010 15:35    Post subject: Reply with quote

Flasher wrote:
Я чего-то ничего не пойму. Ты предлагал сделать самому замену переносов строки на /n?

Да Smile

Ну, если ты так хочешь, можешь вставить в начало скрипта автоматическое преобразование буфера:
Code:
With CreateObject("TCScript.Helper")
  .SetTextToClip(Replace(.GetTextFromClip, vbNewLine, "\n"))
End With

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



Joined: 02 Mar 2005
Posts: 392

Post (Separately) Posted: Tue Oct 05, 2010 15:41    Post subject: Reply with quote

Flasher wrote:
Поправьте, если я ошибаюсь, в VBS это не достижимо.
Самые обычные регексп замены с ключами Multiline и Global.
Back to top
View user's profile Send private message
Loopback



Joined: 07 Sep 2009
Posts: 1279

Post (Separately) Posted: Tue Oct 05, 2010 15:52    Post subject: Reply with quote

Flasher wrote:
"Табов" в каком смысле? Типа вкладок или всё-таки таблицы? Последний вариант самый простой, но хотелось бы сразу вставить все куски и выполнить по одному клику, пусть и за несколько проходов.

Ну вкладки, да.
Можно, конечно, создать колонку из полей ввода, но интерфейс сильно вниз растянется, коряво как-то.
Back to top
View user's profile Send private message
Flasher



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

Post (Separately) Posted: Tue Oct 05, 2010 15:56    Post subject: Reply with quote

Batya wrote:
Да Smile
Долго, нужно не один такой кусок к замене представлять.
Batya wrote:
Ну, если ты так хочешь, можешь вставить в начало скрипта автоматическое преобразование буфера:
Так, окей, уже лучше, а что с табуляцией делать?

Lev
Дык, по-моему, тоже со строками только работает. Question

Loopback
А табличный вариант не получится? С ним быстрей просто.
Back to top
View user's profile Send private message
Rodny



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

Post (Separately) Posted: Tue Oct 05, 2010 16:22    Post subject: Reply with quote

Flasher wrote:
Exe-шник первого скрипта устроит?

У меня проблема в том, что я точно знаю только название секции, т. е. я не могу здесь задать строки для поиска.
По идее, должны же быть какие-нибудь ini-специфические функции.

Гы, подумал, как может называться такая функция, вбил в поиск "WriteIniSection". Вы не поверите... Laughing
Попробую что-нибудь сам сочинить на досуге.
Back to top
View user's profile Send private message
Loopback



Joined: 07 Sep 2009
Posts: 1279

Post (Separately) Posted: Tue Oct 05, 2010 16:23    Post subject: Reply with quote

Flasher wrote:
А табличный вариант не получится? С ним быстрей просто.

Если имеется в виду таблица типа экселевской - то в WinAPI такой нет. SysListView, если мне не изменяет память, тоже не поддерживает многострочный текст.
Так что либо так, либо этак, либо еще как-нибудь Smile.
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 Previous  1, 2, 3, 4, 5, 6, 7, 8, 9  Next
Page 2 of 9

 
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