Войти

Показать полную графическую версию : [Архив - Часть 1.2] AutoIt скрипты


Страниц : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 [23] 24 25 26

VelDmi
04-11-2006, 13:10
Creat0R
Попрубуй так:
Код:
$NerocmdTxt = WinGetText("Заголовок консоли", "")
Не работает. Более того, AutoItInfo тоже не видит никакого текста в окне консоли. Еще есть идеи?

amel27
05-11-2006, 09:42
Creat0R
$Array = StringSplit("1|4|6|8", "|")ну ты умеешь озадачить... зачем делать сплит строки если предложенная функция возвращает уже готовый массив с номерами строк?
если дубликатов нет, ненужно выводить сообщения, а просто в массив с нулём ($Array[0])именно такой массив ф-ция и возвращает, только не одномерный, а двумерный - ты же вроде заказывал не только номера строк ($Array[$i][0]), но и их содержимое ($Array[$i][1])? Счетчик $Array[0][0] содержит число возвращенных строк - если он равен 0, то вхождений соответственно нет. SELECT добавлен для наглядности, я же вроде сказал что его можно убрать.
Но и тут есть проблема, после удаления строки под первым номером присутствующем в массиве, все остальные теряют своё значения, и удаляются уже не те строки эта проблема решается просто - нужно проходить массив в обратном направлении: от конца файла к его началу:#include <File.au3>

$File = "c:\test.txt"
$Array = _TextInFile ($File, "Просто текст")
If $Array[0][0]>1 Then
For $i = $Array[0][0] to 2 Step -1
_FileWriteToLine($File, $Array[$i][0], "", 1)
Next
EndIf

Func _TextInFile ($file, $text)
Local $i, $txtLines, $res [1][2] = [[0,0]]
_FileReadToArray ($file, $txtLines)
If IsArray ($txtLines) Then
For $i=1 To $txtLines [0]
If StringInStr ($txtLines [$i], $text) Then
ReDim $res [$res [0][0]+2][2]
$res [0][0] = $res [0][0] +1
$res [$res [0][0]][0] = $i
$res [$res [0][0]][1] = $txtLines [$i]
EndIf
Next
EndIf
Return $res
EndFunc

Creat0R
05-11-2006, 23:47
amel27
Приогромное спасибо! Я думал что функция для моей задумки, будет выглядеть намного длинее :)

В связи с тем, что эта функция относительно быстро срабатывает (я проверял на большом файле с текстом), у меня появился вопрос...

У меня есть функция (от Sanja Alone), которая делает поиск по файлу, и если текст найден, то возвращается в Array[0] номер строки где был найден текст, а в Array[1] возвращается состав этой строки. Так вот, та функция, визуально большая, и большие файлы обрабатывает довольно долго (доходит до 5-ти секунд). И ещё, возвращается только первое-найденное вхождение, а хотелось бы точно также как и с твоей функцией, чтобы в массив возвращались все номера строк, и все содержания этих строк.

В общем, вопрос в том, можно ли немного переделать эту функцию, чтобы вместо поиска дубляжей, искалось просто слово, и возвращались те же значения, что и в этой функции? (чтобы также можно было воспользоваться ими, ну, допустим для замены текста на что то другое - для этого у меня уже есть функция).

amel27
06-11-2006, 04:20
Creat0Rта функция, визуально большая, и большие файлы обрабатывает довольно долго (доходит до 5-ти секунд). Смотри текст скрипта - у Sanja Alone дополнительно реализована нечувствительность к регистру для русского текста (для английского это выполняется автоматически), возможно поэтому он и работает медленнее...

вопрос в том, можно ли немного переделать эту функцию, чтобы вместо поиска дубляжей, искалось просто слово, и возвращались те же значения, что и в этой функции?м-да... подставь в функцию вместо "дубля" искомое "слово", и функция вернет "те же значения"... ;)
в чем разница-то?.. возвращаются всегда все значения, просто при замене использовались не все (смотри пределы):For $i = $Array[0][0] to 2 Step -1
...
Next

Creat0R
06-11-2006, 09:55
amel27
Ещё раз спасибо. В данном случае, нет необходимости в поиске текста содержащий кириллицу (разве что бывают ссылки с кириллицей :) ).

TERMINAL
06-11-2006, 16:32
1. Creat0R спасибо за скрипт, но он всеравно не подходит. В твоём скрипте постоянно, бесконечно стартует Setup.exe

При установке программы (например-Setup.exe) может вывалиться окно с ошибкой ERROR (ошибка вылетает в том случае если неустановлены видео драйвера), а может и не вывалиться (если же установлены видео драйвера). Так вот, хотелось бы чтобы скрипт работал как с установленными дровами так и без них. Т.е. при старте Setup.exe может установка прекратиться и вылезет окно ERROR-так можно этот файл стартовать до 3х раз-потом уже ошибка не вылетает и прога начинает устанавливаться, а может ошибка и не вылезти.

=======================================================

2. ПОМОГИТЕ НАЙТИ ОШИБКУ !!!
Мне нужно убрать галочки при инсталяции (именно мышкой <ControlClick>)-написал такой скрипт, но он не убират галочки:

WinWait("InstallShield Wizard","InstallShield Wizard Complete")
WinActivate("InstallShield Wizard","InstallShield Wizard Complete")
ControlClick("InstallShield Wizard","InstallShield Wizard Complete","Static1")
ControlClick("InstallShield Wizard","InstallShield Wizard Complete","Static1")

Creat0R
06-11-2006, 16:53
TERMINAL

постоянно, бесконечно стартует Setup.exe
Присмотрись в скрипт, там указанно окно при пресутствии которого, скрипт опять запустит Setup.exe

вылезет окно ERROR
Кажется это было окно "MM" ;) ...

If WinExists("ERROR", "") Then ;Если окно с заголовком ERROR существует, то....
WinClose("ERROR", "") ;Закрываем это окно
ContinueLoop ;продолжаем (начинаем) скрипт сначала (запустив Setup.exe опять)
EndIf ;Конец условия (“Если окно с заголовком ERROR существует, то....”)
ExitLoop ;Выход из цикла (без запуска Setup.exe)

он не убират галочки
Он убирает, и, ставит сразу обратно :) - у тебя две одинаковые строки (два нажатия мышкой в одном и том же чекбоксе)...

ControlClick("InstallShield Wizard","InstallShield Wizard Complete","Static1")
ControlClick("InstallShield Wizard","InstallShield Wizard Complete","Static1")

Убери (или измени) один, и будет ставить галку (если все параметры верные).

Creat0R
06-11-2006, 20:17
amel27
Есть ещё небольшой вопрос, также немного затрагивающий функцию поиска дубликатов...

Возможно ли сделать поиск по файлу на дубликаты, но заранее не знаяя вхождения? т.е нужно проверить все существующие строки в файле, и если хоть какая то из них имеет дубликат (именно по строке), то удалить все точно такие же строки, но оставив оригинал (для каждой такой найденной строки, произвести данную операцию - т.е удаление дубликатов найденных строк). Но, подвог (для меня) в том, что нужно удалить не именно те строки (их дубликаты), а те которые располагаются на три строчки выше.

Вот пример файла:

Первая строка
Ещё строка - > вот это и нужно чтобы удалилось (так как на три строки ниже, есть дубль той строки, которая на одну ниже этой (но её положение не фажно))
и ещё строка
просто текст
и ещё строка
и ещё больше текста
строка номер 7 - > и вот это нужно чтобы удалилось
строка 8
и текст строки номер 9
И ещё больше текста


P.S.
В данном случае, скорость обработки, не очень уж важно, да и визуализация тоже :) - Главное функционал!

amel27
07-11-2006, 11:21
Creat0Rещё небольшой вопроспримерно так... Пара замечаний - во-первых, оператор "=" (для целых строк) в отличие от StringInStr (для вхождений) дружит с русским языком и это хорошо... во-вторых, строки с дополнительными пробелами в конце/начале строк будут рассматриваться как различные, если это не устраивает нужно применить функцию StringStripWS.
#include <File.au3>

$File = "c:\test.txt"

Dim $FileLines
_FileReadToArray ($file, $FileLines)
; Возвращаем массив из дублирующихся записей
$DupLines = _DupsInArray ($FileLines)
; Страховка от пустого массива если дублей нет
If $DupLines [0][0] >0 Then
; Рабочий массив для отметок удаляемых записей
Local $DelFlags [$FileLines [0] +1]
For $i=1 To $DupLines [0][0]
; расчитываем номер строки для удаления
$delNum = $DupLines [$i][0] - 3
; отмечаем кандидата на удаление в массиве
$DelFlags [$delNum] = 1
Next
; Собственно цикл удаления
For $i = $FileLines [0] To 1 Step -1
If $DelFlags [$i] = 1 Then
_FileWriteToLine ($File, $i, "", 1)
EndIf
Next
EndIf

; Возвращает двумерный массив со счетчиком, содержащий только дубли
Func _DupsInArray (ByRef $array)
Local $i, $i, $res [1][2] = [[0,0]]
; рабочий массив для отметки обработанных дублей
Local $flags [$array [0] +1]
For $i=1 To $array [0]
For $j=$i+1 To $array [0]
If $flags [$j] <> 1 Then
If $array [$i] = $array [$j] Then
ReDim $res [$res [0][0]+2][2]
$res [0][0] = $res [0][0] +1
$res [$res [0][0]][0] = $j
$res [$res [0][0]][1] = $array [$j]
$flags [$j] = 1
EndIf
EndIf
Next
Next
Return $res
EndFunc

Creat0R
07-11-2006, 12:01
amel27
Я извеняюсь, я не обращал внимания, но в том файле, для которго это будет делаться, есть дубли которые не должны быть тронуты. Т.е я даже заранее знаю начало строки - URL= но перед этим идёт таб (@Tab)... в общем, вот часть этого файла (это закладки от браузера Opera):


#URL
ID=16
NAME=ICQ2Go!
URL=http://www.icq.com/icq2go/flicq.html
ICONFILE=www.icq.com.ico
IN PANEL=YES
PANEL_POS=10

#URL
ID=17
NAME=Сетевые инструменты
URL=file://C:/Program Files/Opera/help/tools/tools.htm
ICONFILE=tools.ico
IN PANEL=YES
PANEL_POS=13

#URL
ID=18
NAME=Просмотр Кеша
URL=file://C:/Program Files/Opera/help/Opera_Cache_Viewer76/viewer.htm
ICONFILE=cash.ico
IN PANEL=YES
PANEL_POS=14

#URL
ID=19
NAME=ICQ2Go!
URL=http://www.icq.com/icq2go/flicq.html
ICONFILE=www.icq.com.ico
IN PANEL=YES
PANEL_POS=10

#URL
ID=20
NAME=Просмотр Кеша
URL=file://C:/Program Files/Opera/help/Opera_Cache_Viewer76/viewer.htm
ICONFILE=cash.ico
IN PANEL=YES
PANEL_POS=14

Так вот, тут видно, что есть много дублей, но не все нужно трогать, а именно те, которые имеют начало URL= (ссылка потом может быть любая). И нужно чтобы удалилась строчка, содержащая это - #URL (т.е она расположена на три строки выше чем совпавший дубль). Я пометил красным те строки, которые именно в этом куске, и должны будут быть удалены в конце обработки.

amel27
07-11-2006, 13:02
Creat0R
просто добавь еще один IF:...
For $i=1 To $DupLines [0][0]
If StringLeft ($DupLines [$i][1], 5) = @TAB & "URL=" Then
; расчитываем номер строки для удаления
$delNum = $DupLines [$i][0] - 3
; отмечаем кандидата на удаление в массиве
$DelFlags [$delNum] = 1
EndIf
Next
...... судя по файлу это больше смахивает на работу с блоками текста, чем просто со строками

Creat0R
07-11-2006, 16:39
amel27
просто добавь еще один IF:
Огромное THENX! - Как всё оказывается просто :)

судя по файлу это больше смахивает на работу с блоками текста, чем просто со строками
Ну да, просто содержимое этого файла, может доходить до 5-ти, а то и 10-ти ТЫСЯЧЬ! строк (иногда и больше) - и это всё закладки в браузере Opera (как избранное у IE), данная функция, позволит удалить в этом файле все дублирующиеся закладки. Просто если удалить у любого такого блока, строчку содержащюю #URL, то после запуска браузера, эта закладка не будет отображаться, и даже более этого, браузер сам всё “поправит” в файле, и “затрёт” оставшиеся строчки, которые для него, как бы являются “мусором”.

amel27
08-11-2006, 02:04
Creat0Rесли удалить у любого такого блока, строчку содержащюю #URL, то после запуска браузера, эта закладка не будет отображаться, и даже более этого, браузер сам всё “поправит” в файле, и “затрёт” оставшиеся строчкивсе это замечательно... но представь, что в блоке поменялись местами две строчки (подправит ли это браузер, это ведь не ошибка?), или в новой версии добавили новый реквизит... работа скрипта будет нарушена. Поэтому более "правильным" представляется следующий алгоритм:
- читаем файл и сразу нумеруем записи по блокам (а не по строкам);
- один из реквизитов (URL) оформляем как ключевой для блока;
- формируем новый файл ссылок (поверх старого), но уже без дублей.

З.Ы. обычно чем "правильней" алгоритм, тем он медленней

Creat0R
08-11-2006, 04:46
amel27
представь, что в блоке поменялись местами две строчки (подправит ли это браузер, это ведь не ошибка?)
Именно те строчки, которые в промежутке #URL и URL=ссылка, меняться местами не могут, и вообще, все строчки всегда присутствуют так, как это задуманно браузером, я пробовал убирать строки по разному, но браузер ставил так как ему нужно.

в новой версии добавили новый реквизит
Сомневаюсь я, что разработчики когда либо возьмутся за правку работы с закладками, в браузере и так много чего править нужно, и вещи куда серъёзней чем закладки :) (хотя предусмотреть такую функцию, как не позволения добовлять закладки повторно, они конечно должны были).

обычно чем "правильней" алгоритм, тем он медленней
Но мне скорость не очень важна, я конечно буду очень рад если будет более усовершенствованный скрипт :), но так как он выполняется сейчас, меня вполне устраивает. Ещё раз спасибо.

amel27
08-11-2006, 12:28
Creat0Rя конечно буду очень рад если будет более усовершенствованный скрипт , но так как он выполняется сейчас, меня вполне устраивает.другого не будет :) ...и тем не менее (на будущее) советую не заниматься сочинительством отвлеченных задачек, а сразу раскрывать все требования к скрипту. Кодирование общих задач может и полезно, но требует учета большего количества вариантов, что приводит к лишней трате времени и лишней длине кода... лучше постановку задачи сделать совместными усилиями. ;)

применительно к твоему скрипту код можно еще укоротить:
#include <File.au3>

$File = "c:\test.txt"

Dim $FileLines
_FileReadToArray ($file, $FileLines)
; Возвращаем массив из дублирующихся записей
$DupLines = _DupsInArray ($FileLines)
; Страховка от пустого массива если дублей нет
If $DupLines [0][0] >0 Then
For $i=$DupLines [0][0] To 1 Step -1
If StringLeft ($DupLines [$i][1],5) = @TAB & "URL=" Then _FileWriteToLine ($File, $DupLines [$i][0] - 3, "", 1)
Next
EndIf
З.Ы. я ваще нудный... =)

Creat0R
08-11-2006, 13:35
amel27
лучше постановку задачи сделать совместными усилиями.
Ок, буду далее только с открытыми картами появляться :) - просто по какой то причине, мне всё время кажется, что этими самыми “сочинениями”, мне удастса лучше объяснить цель моей задачи.

применительно к твоему скрипту код можно еще укоротить:
Спасибо, но как оказалось, ты в каком то смысле был прав :( ...

Дело вот в чём, браузер не всегда затирает нужные закладки, иногда, если были удалены заглавы (#URL) двух закладок (блоков) идущих подряд, то он удаляет иногда и ту закладку которая идёт выше этих двух. Может всё же как то можно чтобы уже сразу весь блок удалять? :blush2:

я ваще нудный
Желаю чтобы все пользователи этого форума были такими нудными, я бы тогда здесь по жизннно зависал :) - и вообще, нет ли такой возможности (может тоже скрипт написать?), чтобы за каждое твоё оставленное сообщение (пусть даже по всему форуму), автоматом оно обозначалось бы как “Полезное сообщение” - оно так и есть :)

amel27
09-11-2006, 03:54
Creat0RДело вот в чём, браузер не всегда затирает нужные закладки, иногда, если были удалены заглавы (#URL) двух закладок (блоков) идущих подряд, то он удаляет иногда и ту закладку которая идёт выше этих двух. Может всё же как то можно чтобы уже сразу весь блок удалять?Сказал же, другого не будет :) ... Лучше воспользоваться твоим утверждением о фиксированном формате блока и чуть переделать существующий:
1. перенес IF в код функции - это необязательно, но оптимизирует поиск дублей,
2. добавил удаление остальных строк блока (в обратном порядке!).#include <File.au3>

$File = "c:\test.txt"

Dim $FileLines
_FileReadToArray ($file, $FileLines)
; Возвращаем массив из дублирующихся записей
$DupLines = _DupURLsInArray ($FileLines)
; Страховка от пустого массива если дублей нет
If $DupLines [0][0] >0 Then
For $i=$DupLines [0][0] To 1 Step -1
_FileWriteToLine ($File, $DupLines [$i][0] +3, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] +2, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] +1, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] , "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] -1, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] -2, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] -3, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] -4, "", 1)
Next
EndIf

; Возвращает двумерный массив со счетчиком, содержащий только дубли
Func _DupURLsInArray (ByRef $array)
Local $i, $i, $res [1][2] = [[0,0]]
; рабочий массив для отметки обработанных дублей
Local $flags [$array [0] +1]
For $i=1 To $array [0]
If StringLeft ($array [$i],5) = @TAB & "URL=" Then
For $j=$i+1 To $array [0]
If $flags [$j] <> 1 Then
If $array [$i] = $array [$j] Then
ReDim $res [$res [0][0]+2][2]
$res [0][0] = $res [0][0] +1
$res [$res [0][0]][0] = $j
$res [$res [0][0]][1] = $array [$j]
$flags [$j] = 1
EndIf
EndIf
Next
EndIf
Next
Return $res
_ArraySort ($res, 0, 1, 0, 2)
EndFunc
чтобы за каждое твоё оставленное сообщение (пусть даже по всему форуму), автоматом оно обозначалось бы как “Полезное сообщение” - оно так и есть не переживай - это пройдет... :)

Creat0R
09-11-2006, 09:20
amel27
Тоже есть трабла :( .

Оказывается :) , иногда некоторых пунктов в этом блоке нету\есть, они не присутствует\присутствуют в том случае, либо, если у закладки нет\есть описании (DESCRIPTION), либо нет\есть код посещения (VISITED=), либо нет\есть код активвности (ACTIVE=). Вот как выглядит самый полный блок (т.е больше этих пунктов нет) :

#URL
ID=1
NAME=AutoIt скрипты .:[общие вопросы]:.
URL=http://forum.oszone.net/post-508967.html
CREATED=1163050009
VISITED=1163050722
DESCRIPTION=AutoIt скрипты .:[общие вопросы]:.
ICONFILE=forum.oszone.net.gif
ACTIVE=YES

А вот как будет выглядеть блок с минимальными пунктами (меньше чем это не может быть) :


#URL
ID=21
NAME=Yahoo!
URL=http://www.yahoo.com/
CREATED=1163050735
ICONFILE=www.yahoo.com.ico


Я бы конечно мог просчитать все варианты, т.е если есть допустим пункт DESCRIPTION=, и нету пункта VISITED=, то делаем одно действие, а если есть первое и нет второго, то делаем другое, и т.д... но это получится слишком громоздко, вот начало этого...


For $i=$DupLines [0][0] To 1 Step -1
If StringLeft(FileReadLine($File, $DupLines [$i][0] +3), 13) = @TAB & "DESCRIPTION=" and StringLeft(FileReadLine($File, $DupLines [$i][0] +2), 9) = @TAB & "VISITED=" Then
_FileWriteToLine ($File, $DupLines [$i][0] +4, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] +3, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] +2, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] +1, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] , "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] -1, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] -2, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] -3, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] -4, "", 1)
ElseIf StringLeft(FileReadLine($File, $DupLines [$i][0] +2), 13) = @TAB & "DESCRIPTION=" and StringLeft(FileReadLine($File, $DupLines [$i][0] +5), 8) = @TAB & "ACTIVE="
_FileWriteToLine ($File, $DupLines [$i][0] +5, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] +4 "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] +3, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] +2, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] +1, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] , "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] -1, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] -2, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] -3, "", 1)
_FileWriteToLine ($File, $DupLines [$i][0] -4, "", 1)
EndIf
Next

Может есть способ покороче с этим бороться?
Вот на всякий пожарный, прикладываю файл, содержащий дубликаты таких (разных) блоков.

amel27
09-11-2006, 11:57
Creat0RТоже есть трабла на то и вышло... :) чтобы удалить блок нужно определить его конец и начало:
#include <File.au3>
#include <Array.au3>

$File = "c:\test.txt"

Dim $FileLines
_FileReadToArray ($file, $FileLines)
; Возвращаем массив из дублирующихся записей
$DupLines = _DupURLsInArray ($FileLines)
; Страховка от пустого массива если дублей нет
If $DupLines [0][0] >0 Then
For $i=$DupLines [0][0] To 1 Step -1
; ищем начало следующего блока
$iNext = _ArraySearch ($FileLines, "#URL", $DupLines [$i][0])
; если не нашли, то конец файла
If @Error=6 Then $iNext=_FileCountLines ($File) +1
Do
$iNext=$iNext-1
_FileWriteToLine ($File, $iNext, "", 1)
Until $FileLines [$iNext] = "#URL"
Next
EndIf
EDIT: исправил ошибку с уловием (выделено красным), спутал с функцией _ArrayBinarySearch

Creat0R
09-11-2006, 23:21
amel27
Удаляются не все дублирующиеся блоки :( - и как ни странно, не удалился дубль именно закладки этого поста :) (эксперементировал на прикреплённом мной раньше файле).




© OSzone.net 2001-2012