Страница 2 из 9
Добавлено: Вт окт 05, 2010 13:00
Batya
Flasher писал(а):Речь о формировании временных файлов с текстом поиска/замены (в папке %TEMP%, по всей видимости). Или если какой-то более изощрённый способ?
Текст также, как и у
Loopback, будет грузиться в память. Вопрос по объёму файла актуален и для того варианта, который собираюсь реализовать я.
Добавлено.
Вообщем-то, тут особо и писать нечего.
Всё в том же
скрипте от Volny после строки
Код: Выделить всё
Find_String = InputBox("Введите искомую строку", "Поиск и замена")
добавь
Код: Выделить всё
Find_String = Replace(Find_String, "\n", vbNewLine)
И после строки
Код: Выделить всё
Replace_String = InputBox("Введите строку для замены", "Поиск и замена")
добавь
Код: Выделить всё
Replace_String = Replace(Replace_String, "\n", vbNewLine)
Добавлено: Вт окт 05, 2010 13:10
Loopback
Flasher
Тут есть два пути: или отказаться от библиотек, заменив константы из них значениями (что не очень удобно), или скомпилировать скрипт не в экзашник, а в байт-код. Получится один файл, с расширением a3x, который можно запускать как обычный au3, но который уже будет включать все необходимые библиотеки. Для этого в утилите Aut2exe нужно выбрать тип для Destination как "Encoded script files".
И кстати, тут я немного поспешил с библиотеками - можно смело оставить только GUIConstantsEx.au3.
Добавлено: Вт окт 05, 2010 13:12
Flasher
CaptainFlint писал(а):Я как раз и подразумевал, что программа может обрабатывать лишь по одному файлу за раз, тогда lst2multi и приведёт к многократному вызову утилиты для каждого файла в отдельности.
Скорее всего
Вахмурка подразумевал утилиту, где задаётся список либо путь к файлам, и тут вовсе не имелся в виду редактор MDI/SDI, с которым lst2mlt и lst2str умеют работать. Ну а многократный вызов SDI-приложения вообще не вариант..
Добавлено: Вт окт 05, 2010 13:27
Flasher
Batya
Понял, сделаю. Спасибо!
Насчёт рекурсии какие там дела?
Loopback писал(а):скомпилировать скрипт не в экзашник, а в байт-код. Получится один файл, с расширением a3x, который можно запускать как обычный au3, но который уже будет включать все необходимые библиотеки
А ведь точно.
Loopback писал(а):И кстати, тут я немного поспешил с библиотеками - можно смело оставить только GUIConstantsEx.au3
Замечательно! Всё свелось к 2 Кб.

Добавлено: Вт окт 05, 2010 14:07
Flasher
Loopback
Я вот ещё о чём подумал. Бывает, что надо заменить несколько разных кусков, разбросанных в разных местах кода/текста на один единственный. Вот хотелось бы (если это возможно) разбивать левое окно на заданное в параметрах кол-во частей ( можно ограничить до 6-8 ), в каждое поле которых будет заносится свой кусок текста. Есть такая возможность?
Добавлено: Вт окт 05, 2010 14:23
Batya
Flasher писал(а):Насчёт рекурсии какие там дела?
Замени процедуру DoItForThisFile на:
Код: Выделить всё
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
Добавлено: Вт окт 05, 2010 14:49
Rodny
А можно я со своим реквестом (но в рамках темы) влезу?
У меня частный случай: два INI в кодировке UTF-8. Можно ли заданную секцию (целиком) из первого файла скопировать во второй, заменив имеющуюся? Можно упростить задачу: в первом файле только эта одна секция.
Пути файлов и названия секций либо в самом скрипте, либо в параметрах кнопки, непринципиально.
Т.е. никакого интерфейса не требуется, в один клик.
P.S. Оно может уже есть, но вроде не припоминаю, ткните тогда носом, если у кого ссылка под рукой.
P.P.S. Поскольку с AutoIt'ом сталкиваться ещё не доводилось, ставить/компилировать несколько напряжно, если можно будет обойтись vbs, это предпочтительнее.
Добавлено: Вт окт 05, 2010 14:59
Loopback
Flasher
Ну вот примерно так.
Код: Выделить всё
#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 писал(а):Я вот ещё о чём подумал. Бывает, что надо заменить несколько разных кусков, разбросанных в разных местах кода/текста на один единственный. Вот хотелось бы (если это возможно) разбивать левое окно на заданное в параметрах кол-во частей ( можно ограничить до 6-8 ), в каждое поле которых будет заносится свой кусок текста. Есть такая возможность?
Да в принципе всё возможно. Только "окно на части" - это как? Тогда уж проще динамически сделать несколько табов с полями ввода. Ну или просто не закрывать окно после выполнения и менять код в первом поле.
Добавлено: Вт окт 05, 2010 15:03
Flasher
Batya
Я чего-то ничего не пойму. Ты предлагал сделать самому замену переносов строки на /n? Ведь в скрипте всё осталось по старому по части окон. Если я заношу в буфер кусок текста, то скрипт с учётом неактивности не сможет преобразовать этот кусок в строку, а значит я смогу вставить только первую строчку и то при условии, если она не будет начинаться с переноса, пробела или табуляции, а это очень нехорошо..
Rodny писал(а):Поскольку с AutoIt'ом сталкиваться ещё не доводилось, ставить/компилировать несколько напряжно
Exe-шник первого скрипта устроит?
Loopback писал(а):Да в принципе всё возможно. Только "окно на части" - это как? Тогда уж проще динамически сделать несколько табов с полями ввода. Ну или просто не закрывать окно после выполнения и менять код в первом поле.
"Табов" в каком смысле? Типа вкладок или всё-таки таблицы? Последний вариант самый простой, но хотелось бы сразу вставить все куски и выполнить по одному клику, пусть и за несколько проходов.

Добавлено: Вт окт 05, 2010 15:35
Batya
Flasher писал(а):Я чего-то ничего не пойму. Ты предлагал сделать самому замену переносов строки на /n?
Да
Ну, если ты так хочешь, можешь вставить в начало скрипта автоматическое преобразование буфера:
Код: Выделить всё
With CreateObject("TCScript.Helper")
.SetTextToClip(Replace(.GetTextFromClip, vbNewLine, "\n"))
End With
Добавлено: Вт окт 05, 2010 15:41
Lev
Flasher писал(а):Поправьте, если я ошибаюсь, в VBS это не достижимо.
Самые обычные регексп замены с ключами Multiline и Global.
Добавлено: Вт окт 05, 2010 15:52
Loopback
Flasher писал(а):"Табов" в каком смысле? Типа вкладок или всё-таки таблицы? Последний вариант самый простой, но хотелось бы сразу вставить все куски и выполнить по одному клику, пусть и за несколько проходов.
Ну вкладки, да.
Можно, конечно, создать колонку из полей ввода, но интерфейс сильно вниз растянется, коряво как-то.
Добавлено: Вт окт 05, 2010 15:56
Flasher
Batya писал(а):Да

Долго, нужно не один такой кусок к замене представлять.
Batya писал(а):Ну, если ты так хочешь, можешь вставить в начало скрипта автоматическое преобразование буфера:
Так, окей, уже лучше, а что с табуляцией делать?
Lev
Дык, по-моему, тоже со строками только работает.
Loopback
А табличный вариант не получится? С ним быстрей просто.
Добавлено: Вт окт 05, 2010 16:22
Rodny
Flasher писал(а):Exe-шник первого скрипта устроит?
У меня проблема в том, что я точно знаю только название секции, т. е. я не могу здесь задать строки для поиска.
По идее, должны же быть какие-нибудь ini-специфические функции.
Гы, подумал, как может называться такая функция, вбил в поиск "WriteIniSection". Вы не поверите...
Попробую что-нибудь сам сочинить на досуге.
Добавлено: Вт окт 05, 2010 16:23
Loopback
Flasher писал(а):А табличный вариант не получится? С ним быстрей просто.
Если имеется в виду таблица типа экселевской - то в WinAPI такой нет. SysListView, если мне не изменяет память, тоже не поддерживает многострочный текст.
Так что либо
так, либо
этак, либо еще как-нибудь

.