View previous topic :: View next topic |
Author |
Message |
Flasher

Joined: 06 Nov 2009 Posts: 14229 Location: Москва
|
(Separately) Posted: Tue Oct 12, 2010 23:38 Post subject: Добавление текста до/после строк в выделенных файл-списках |
|
|
Давно появилась задача по редактированию строк в файл-списках.
Вот что примерно хотелось бы видеть:
Для AutoIt: одно окно с восьмью полями:
Маска файлов [__]
_________________Вставка текста________________
Слева от строки__[__]___начинающейся с_______[__]*
Справа от строки_[__]___заканчивающейся на___[__]*
Над строкой_____[__]___начинающейся с_______[__]*
Под строкой._____[__]__заканчивающейся на____[__]*
* Если какие-то поля справа пустуют, а слева нет, то обрабатываются все строки по заданным условиям в левых полях.
Для VBS: 4 окна, которые вызываются с учётом заданных через пробел параметров.
1 - вызывает окно "Вставьте текст слева от строки"
2 - вызывает окно "Вставьте текст справа от строки"
3 - вызывает окно "Вставьте текст над строкой"
4 - вызывает окно "Вставьте текст под строкой"
Необходимо комбинировать(1 2 | 2 4 | 1 3 4 и т.д.).
Для обоих случаев:
- если поля "..над строкой" и "..под строкой" пустуют, то не должны создаваться пустые строки;
- исходные пустые строки в файлах не должны обрабатываться(можно добавить параметр на их удаление).
P.S. C vbs я и сам могу поковыряться, просто у меня это времени поболе займёт. |
|
Back to top |
|
 |
Loopback
Joined: 07 Sep 2009 Posts: 1535
|
(Separately) Posted: Wed Oct 13, 2010 15:45 Post subject: |
|
|
Честно говоря вообще не понял логики, как что должно работать. Например:
Слева от строки__[__]___начинающейся с_______[__]*
Справа от строки_[__]___заканчивающейся на___[__]*
Что представляет собой значение "Слева от строки"? Номер строки?
Или если это текст строки, зачем нужно "начинающейся с"?
Да и вообще, как тогда понимать "над" и "под" строкой? В этом случае, получается, строку надо брать целиком. |
|
Back to top |
|
 |
Flasher

Joined: 06 Nov 2009 Posts: 14229 Location: Москва
|
(Separately) Posted: Wed Oct 13, 2010 15:51 Post subject: |
|
|
Loopback wrote: | Что представляет собой значение "Слева от строки"? Номер строки? | Вставка текста слева от любой строки в списке.
Пример:
1 строка: 2222357
2 строка: 4543638
Добавить слева:
блабла
блаблабла
блабла
Результат:
блабла
блаблабла
блабла2222357
блабла
блаблабла
блабла4543638
Loopback wrote: | Или если это текст строки, зачем нужно "начинающейся с"? | Это нужно в случае, если требуется фильтр строк. Т.е. выборочное добавление.
Loopback wrote: | Да и вообще, как тогда понимать "над" и "под" строкой? | Над строкой - на предыдущей строке(ах), под строкой - начиная со следующей строки.
результат вставки над строкой:
блабла
блаблабла
блабла
2222357
блабла
блаблабла
блабла
4543638 |
|
Back to top |
|
 |
Loopback
Joined: 07 Sep 2009 Posts: 1535
|
(Separately) Posted: Wed Oct 13, 2010 16:41 Post subject: |
|
|
Flasher wrote: | Вставка текста слева от любой строки в списке. |
Эээ. Если любой, то нафиг тут тогда поле ввода? Наверно достаточно фильтра? Т.е.
Слева от строки, начинающейся с_______[__]*
Если поле пустое - любая строка.
Кстати, режимы "над" и "под" ничем, по-сути, отличаются от первых двух только добавлением перевода строки. Если в поле ввода вставить дополнительный перенос до или после текста - получим тот же результат. Нужно ли плодить сущности в виде лишних полей? |
|
Back to top |
|
 |
Flasher

Joined: 06 Nov 2009 Posts: 14229 Location: Москва
|
(Separately) Posted: Wed Oct 13, 2010 16:51 Post subject: |
|
|
Loopback wrote: | Если любой, то нафиг тут тогда поле ввода? | Что значит "нафиг"? Это самое важное. Текст туда вообще-то должен вводится, который вставлять надо.
Loopback wrote: | Наверно достаточно фильтра? Т.е. | Я же поясняю, что фильтр нужен для выбора тех строк, около которых будет вводится текст, вставленный в поле слева.
Loopback wrote: | Если поле пустое - любая строка. | Это условие я написал в первом посте, логично.
Loopback wrote: | Нужно ли плодить сущности в виде лишних полей? | Так тут комбинация важна. Вставка у одних строк с фильтром будет спереди/сзади, у других над/под. Плюс ко всему - это удобней, чем приписывать переносы или, допустим, ставить флаги с длинными названиями, которые тоже будут место занимать. |
|
Back to top |
|
 |
Loopback
Joined: 07 Sep 2009 Posts: 1535
|
(Separately) Posted: Wed Oct 13, 2010 17:26 Post subject: |
|
|
Flasher wrote: | Текст туда вообще-то должен вводится, который вставлять надо. |
Ну ты и пишешь Как это можно было понять из текста? В жизни бы не догадался. Я полагал "Вставка текста" - это текст, на который меняем, а всё остальное - условия, в этом случае первые пункты за условие ну никак не катили.
Flasher wrote: | Я же поясняю, что фильтр нужен |
С фильтром как раз всё было понятно. Впрочем, вышесказанное всё расставило на места.
Ок, посмотрю вечером. |
|
Back to top |
|
 |
Flasher

Joined: 06 Nov 2009 Posts: 14229 Location: Москва
|
(Separately) Posted: Wed Oct 13, 2010 17:38 Post subject: |
|
|
Loopback wrote: | Ну ты и пишешь Rolling Eyes Как это можно было понять из текста? | Смотря из какого. Там написано "Вставка текста", а далее ветви(слева.., справа.., над.., под..). Что'ж ещё в поля-то вводить?
Loopback wrote: | Я полагал "Вставка текста" - это текст, на который меняем | Ну про "менять" я нигде не писал, лишь "вставлять". Ты имел в виду, что текст один единственный? Если да, то для него бы я отобразил отдельное поле, которое и могло бы привести в замешательство, а так там его нет.
Loopback wrote: | Ок, посмотрю вечером. | Спасибо! |
|
Back to top |
|
 |
Loopback
Joined: 07 Sep 2009 Posts: 1535
|
(Separately) Posted: Thu Oct 14, 2010 10:04 Post subject: |
|
|
Flasher
Вечером не вышло.
Кстати, как обрабатывать ситуацию, когда заполнены, скажем, первое и третье поле с текстом? Допустим, скрипт обработал первое поле, добавил слева текст. Далее есть еще условие добавления перед. Добавляем перед строкой с уже добавленным слева текстом? Но если при этом задано условие выбора строки - как быть? После добавления текста, по-сути, начало строки меняется.
Чтобы всё было попрозрачнее, предлагаю сделать так: все условия выбора строки делать только по исходной строке. Последовательность обработки текста - сначала присоединять слева(справа), а потом сверху(снизу). |
|
Back to top |
|
 |
Flasher

Joined: 06 Nov 2009 Posts: 14229 Location: Москва
|
(Separately) Posted: Thu Oct 14, 2010 11:27 Post subject: |
|
|
Loopback wrote: | Но если при этом задано условие выбора строки - как быть? После добавления текста, по-сути, начало строки меняется. | Я даже удивился, почему ты вчера сразу об этом не спросил.) Если задано условие выбора, то обработка идёт вкупе с остальными строками. Совпадения могут быть при условии, что юзер просто не знаком с синтаксисом списков, что было бы ОЧЕНЬ странно. Если условие выбора на 1/3 или 2/4 строки не задано одновременно, то в порядке приоритета обрабатываться должны только 1,2 строки(слева, справа), а потом по окончанию 3/4(над, под).
Loopback wrote: | все условия выбора строки делать только по исходной строке. | Секундочку. По какой исходной? Там всего 4 поля с добавляющимся текстом для каждого отдельного случая. Никакого общего текста для всех 4-х вариантов быть не должно. |
|
Back to top |
|
 |
Loopback
Joined: 07 Sep 2009 Posts: 1535
|
(Separately) Posted: Thu Oct 14, 2010 13:17 Post subject: |
|
|
Flasher wrote: | Если условие выбора на 1/3 или 2/4 строки не задано одновременно |
Наверно, имелось в виду все-таки "задано одновременно"?
Flasher wrote: | По какой исходной? |
Ну вот прочитана строка из файла - все фильтры сравниваются с ней, назависимо от того, добавило ли предыдущее условие к ней текст. |
|
Back to top |
|
 |
Flasher

Joined: 06 Nov 2009 Posts: 14229 Location: Москва
|
(Separately) Posted: Thu Oct 14, 2010 13:33 Post subject: |
|
|
Loopback wrote: | Наверно, имелось в виду все-таки "задано одновременно"? | Нет-нет-нет, именно с частицей "не", т.е. если правые поля 1/3, 2/4 пустуют. Ведь в таком случае будут обрабатываться все строки без фильтра кроме пустых, конечно.
Loopback wrote: | Ну вот прочитана строка из файла - все фильтры сравниваются с ней, назависимо от того, добавило ли предыдущее условие к ней текст. | Ааа, в этом смысле. Т.е. не каждый раз прочитывать, а сразу для всех 4-х случаев? Тогда, конечно, ты прав. Только в этом случае я бы хотел добавить флаги с приоритетами. Т.е., если условия справа одинаковые, то приоритет позволит добавлять, например, сперва по "над" перед "слева" или "под" перед "справа". |
|
Back to top |
|
 |
Loopback
Joined: 07 Sep 2009 Posts: 1535
|
(Separately) Posted: Thu Oct 14, 2010 21:06 Post subject: |
|
|
Так, что-то туго дело идет...
Вроде что-то изобразил, но тут сейчас обратил внимание - "файл-списках". Имеется в виду тот файл-список, который создает тотал по %L? А то я как предыдущий сделал, т.е. с поиском и обработкой файлов. |
|
Back to top |
|
 |
Flasher

Joined: 06 Nov 2009 Posts: 14229 Location: Москва
|
(Separately) Posted: Thu Oct 14, 2010 21:20 Post subject: |
|
|
Loopback wrote: | Так, что-то туго дело идет. | Ничего, уж ради такой важной задачи можно и потерпеть.
Loopback wrote: | Имеется в виду тот файл-список, который создает тотал по %L? | В названии темы написано "в выделенных файл-списках". В выделенных папках тоже было бы не плохо файлы по маске редактировать. Списки это или любые другие некодированные файлы(ini, htm(l) , xml, php, txt, lst, cfg, bar, lng, mnu и т.д.)- не суть важно, главное, чтобы алгоритм работал исходя из условий задачи. |
|
Back to top |
|
 |
Loopback
Joined: 07 Sep 2009 Posts: 1535
|
(Separately) Posted: Thu Oct 14, 2010 21:44 Post subject: |
|
|
Ладно, вот что получилось. Сделал как понял, если что не так - будем поправлять в рабочем порядке.
Code: |
;; Параметры: %L
If $CmdLine[0] < 1 Then
MsgBox (0, "", "Недостаточно параметров, должно быть 1.")
Exit
EndIf
Global $aList = _TCHLoadFileList($CmdLine[1])
Global $gBackups = False, $gCaseSence = 0
Global Const $GUI_CHECKED = 1
Global $gRemoveEmpty = False
Global $gIniFile = StringLeft(@ScriptFullPath, StringInStr(@ScriptFullPath, ".", 0, -1)) & "ini"
$hGUI = GUICreate("Вставка текста", 549, 570, -1, -1)
$edTextLeft = GUICtrlCreateEdit("", 8, 96, 529, 73)
$btnOK = GUICtrlCreateButton("OK", 384, 528, 75, 25)
$btnCancel = GUICtrlCreateButton("Отмена", 464, 528, 75, 25)
GUICtrlCreateLabel("начинающейся на", 198, 70, 94, 17, 0x2)
$cbCaseSence = GUICtrlCreateCheckbox("Учитывать регистр", 8, 520, 137, 17)
$edMask = GUICtrlCreateInput("*.*", 8, 24, 265, 21)
GUICtrlCreateLabel("Маска файлов", 8, 6, 78, 17)
$edTextRight = GUICtrlCreateEdit("", 8, 208, 529, 73)
$edTextBefore = GUICtrlCreateEdit("", 8, 320, 529, 73)
$edTextAfter = GUICtrlCreateEdit("", 8, 432, 529, 73)
GUICtrlCreateLabel("заканчивающейся на", 176, 182, 113, 17, 0x2)
GUICtrlCreateLabel("начинающейся на", 196, 294, 95, 17, 0x2)
GUICtrlCreateLabel("заканчивающейся на", 176, 406, 113, 17, 0x2)
$ibFilterLeft = GUICtrlCreateInput("", 296, 66, 241, 21)
$ibFilterRight = GUICtrlCreateInput("", 296, 178, 241, 21)
$ibFilterBefore = GUICtrlCreateInput("", 296, 290, 241, 21)
$ibFilterAfter = GUICtrlCreateInput("", 296, 402, 241, 21)
GUICtrlCreateLabel("", 8, 56, 528, 2, 0x10)
GUIStartGroup()
$Radio1 = GUICtrlCreateRadio("Добавить к строке слева", 8, 69, 153, 17)
GUICtrlSetState(-1, $GUI_CHECKED)
GUICtrlSetTip(-1, "Приоритет над п.3")
$Radio3 = GUICtrlCreateRadio("Добавить сверху строки", 8, 293, 153, 17)
GUICtrlSetTip(-1, "Приоритет над п.1")
GUIStartGroup()
$Radio2 = GUICtrlCreateRadio("Добавить к строке справа", 8, 181, 161, 17)
GUICtrlSetState(-1, $GUI_CHECKED)
GUICtrlSetTip(-1, "Приоритет над п.4")
$Radio4 = GUICtrlCreateRadio("Добавить снизу строки", 8, 405, 153, 17)
GUICtrlSetTip(-1, "Приоритет над п.2")
$cbBackups = GUICtrlCreateCheckbox("Создавать резервные копии", 160, 520, 193, 17)
$cbRemoveEmpty = GUICtrlCreateCheckbox("Удалять пустые строки", 8, 544, 150, 17)
$cbCloseDone = GUICtrlCreateCheckbox("Закрывать по завершению", 160, 544, 160, 17)
Global $AccelTable[1][2] = [["^{ENTER}", $btnOK]]
GUISetAccelerators($AccelTable)
GUISetState(@SW_SHOW)
GUICtrlSetState($cbCaseSence, IniRead($gIniFile, "Settings", "CaseSenseSearch", 4))
GUICtrlSetState($cbBackups, IniRead($gIniFile, "Settings", "MakeBackups", 4))
GUICtrlSetState($cbRemoveEmpty, IniRead($gIniFile, "Settings", "RemoveEmptyLines", 4))
GUICtrlSetState($cbCloseDone, IniRead($gIniFile, "Settings", "CloseWhenDone", 1))
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case -3, $btnCancel
Exit
Case $btnOK
$gMask = _MaskToRegexp(GUICtrlRead($edMask))
$gBackups = BitAND(GUICtrlRead($cbBackups), $GUI_CHECKED)
$gRemoveEmpty = BitAND(GUICtrlRead($cbRemoveEmpty), $GUI_CHECKED)
If BitAND(GUICtrlRead($cbCaseSence), $GUI_CHECKED) Then $gCaseSence = 1
WinSetState($hGUI, "", @SW_DISABLE)
IniWrite($gIniFile, "Settings", "CaseSenseSearch", GUICtrlRead($cbCaseSence))
IniWrite($gIniFile, "Settings", "MakeBackups", GUICtrlRead($cbBackups))
IniWrite($gIniFile, "Settings", "RemoveEmptyLines", GUICtrlRead($cbRemoveEmpty))
IniWrite($gIniFile, "Settings", "CloseWhenDone", GUICtrlRead($cbCloseDone))
For $i = 1 To $aList[0]
If StringRight($aList[$i], 1) = "\" Then
_DoFolder($aList[$i])
Else
_DoFile($aList[$i])
EndIf
Next
MsgBox (0, "", "Завершено.", 0, $hGUI)
If BitAND(GUICtrlRead($cbCloseDone), $GUI_CHECKED) Then Exit
WinSetState($hGUI, "", @SW_ENABLE)
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 _ProcessLines(ByRef $aSrcFile, ByRef $aTrgFile, $sText, $sFilter, $nMode)
If $sText = "" Then Return
For $i = 1 To $aSrcFile[0]
Switch $nMode
Case 0, 2
If ($sFilter <> "") Then
$sLeft = StringLeft($aSrcFile[$i], StringLen($sFilter))
If $gCaseSence Then
If Not ($sLeft == $sFilter) Then ContinueLoop
Else
If $sLeft <> $sFilter Then ContinueLoop
EndIf
EndIf
If $nMode = 2 Then $aTrgFile[$i] = @CRLF & $aTrgFile[$i]
$aTrgFile[$i] = $sText & $aTrgFile[$i]
Case 1, 3
If ($sFilter <> "") Then
$sRight = StringRight($aSrcFile[$i], StringLen($sFilter))
If $gCaseSence Then
If Not ($sRight == $sFilter) Then ContinueLoop
Else
If $sRight <> $sFilter Then ContinueLoop
EndIf
EndIf
If $nMode = 3 Then $aTrgFile[$i] = $aTrgFile[$i] & @CRLF
$aTrgFile[$i] = $aTrgFile[$i] & $sText
EndSwitch
Next
EndFunc
Func _DoFile($sFile)
If StringRegExp(StringLower($sFile), $gMask) = 0 Then Return
Local $aSrcFile = _TCHLoadFileList($sFile)
If $gRemoveEmpty And ($aSrcFile[0] > 0) Then
Local $aTrgFile[$aSrcFile[0]+1] = [0]
For $i = 1 To $aSrcFile[0]
If $aSrcFile[$i] <> "" Then
$aTrgFile[0] += 1
$aTrgFile[$aTrgFile[0]] = $aSrcFile[$i]
EndIf
Next
ReDim $aTrgFile[$aTrgFile[0] + 1]
$aSrcFile = $aTrgFile
Else
Local $aTrgFile = $aSrcFile
EndIf
If BitAND(GUICtrlRead($Radio1), $GUI_CHECKED) Then
_ProcessLines($aSrcFile, $aTrgFile, GUICtrlRead($edTextLeft), GUICtrlRead($ibFilterLeft), 0)
_ProcessLines($aSrcFile, $aTrgFile, GUICtrlRead($edTextbefore), GUICtrlRead($ibFilterBefore), 2)
Else
_ProcessLines($aSrcFile, $aTrgFile, GUICtrlRead($edTextbefore), GUICtrlRead($ibFilterBefore), 2)
_ProcessLines($aSrcFile, $aTrgFile, GUICtrlRead($edTextLeft), GUICtrlRead($ibFilterLeft), 0)
EndIf
If BitAND(GUICtrlRead($Radio3), $GUI_CHECKED) Then
_ProcessLines($aSrcFile, $aTrgFile, GUICtrlRead($edTextRight), GUICtrlRead($ibFilterRight), 1)
_ProcessLines($aSrcFile, $aTrgFile, GUICtrlRead($edTextAfter), GUICtrlRead($ibFilterAfter), 3)
Else
_ProcessLines($aSrcFile, $aTrgFile, GUICtrlRead($edTextAfter), GUICtrlRead($ibFilterAfter), 3)
_ProcessLines($aSrcFile, $aTrgFile, GUICtrlRead($edTextRight), GUICtrlRead($ibFilterRight), 1)
EndIf
If $gBackups Then FileCopy($sFile, $sFile & ".bak", 1) ; бэкап
Local $hFile = FileOpen($sFile, 2)
For $i = 1 To $aTrgFile[0]
FileWriteLine($hFile, $aTrgFile[$i])
Next
FileClose($hFile)
EndFunc
Func _MaskToRegexp($sMask)
$sMask = StringRegExpReplace($sMask, "(\\|\.|\+|\^|\(|\)|\[|\]|\{|\}|\$)", "\\\1")
$sMask = StringReplace($sMask, "?", ".")
$sMask = StringReplace($sMask, "*", ".+?")
Return StringLower("(?i)" & $sMask & "$")
EndFunc
; fast list load function
Func _TCHLoadFileList($sFileName, $nIncBlock = 1000)
Local $asList[$nIncBlock + 1] = [0]
Local $hfList = FileOpen($sFileName, 0)
Local $nCounter = 0
While 1
For $i = 1 To $nIncBlock
$asList[$nCounter + $i] = FileReadLine($hfList)
If @error Then
ReDim $asList[UBound($asList) + $i - $nIncBlock - 1]
ExitLoop(2)
EndIf
Next
$nCounter += $nIncBlock
ReDim $asList[UBound($asList)+$nIncBlock]
Wend
FileClose($hfList)
$asList[0] = UBound($asList)-1
Return $asList
EndFunc
|
Last edited by Loopback on Wed Oct 20, 2010 13:44; edited 3 times in total |
|
Back to top |
|
 |
Flasher

Joined: 06 Nov 2009 Posts: 14229 Location: Москва
|
(Separately) Posted: Thu Oct 14, 2010 22:11 Post subject: |
|
|
О, почти то, что надо!
Пока не тестил, сразу что в глаза бросилось:
названия полей лучше не писать через запятую, иначе условия будут восприниматься как необходимые. Стоит текст до запятой сдвинуть до конца влево, а после вправо( и чтобы они отстояли на одинаковом расстоянии от полей с фильтром).
Слова "слева/справа" лучше поменять местами с "к строке". Так лучше по стилистике.
"Перед"/"после" - может восприниматься как слева/справа, так и над/под. Я бы заменил на "сверху"/"снизу" строки. (У себя, естественно, уже поменял.)
Само окно можно поуже сделать на расстояние от слова "копии" до кнопки ОК + от слова "регистр" до флага.
Хорошо было бы добавить птицу "Закрывать после выполнения".
Поля фильтра желательно сделать равной длины.
Про флаги с приоритетами, надеюсь, не забыл?
Об остальном чуть позже.
Добавлено: что-то не хочет скрипт работать, что с фильтром, что без.
Пробовал с одним файлом под курсором, с выделенным файлом, с выделенными папками. |
|
Back to top |
|
 |
|
|
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
|