Показать полную графическую версию : [Архив - Часть 1.2] AutoIt скрипты
Creat0R
Попрубуй так:
Код:
$NerocmdTxt = WinGetText("Заголовок консоли", "")
Не работает. Более того, AutoItInfo тоже не видит никакого текста в окне консоли. Еще есть идеи?
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
amel27
Приогромное спасибо! Я думал что функция для моей задумки, будет выглядеть намного длинее :)
В связи с тем, что эта функция относительно быстро срабатывает (я проверял на большом файле с текстом), у меня появился вопрос...
У меня есть функция (от Sanja Alone), которая делает поиск по файлу, и если текст найден, то возвращается в Array[0] номер строки где был найден текст, а в Array[1] возвращается состав этой строки. Так вот, та функция, визуально большая, и большие файлы обрабатывает довольно долго (доходит до 5-ти секунд). И ещё, возвращается только первое-найденное вхождение, а хотелось бы точно также как и с твоей функцией, чтобы в массив возвращались все номера строк, и все содержания этих строк.
В общем, вопрос в том, можно ли немного переделать эту функцию, чтобы вместо поиска дубляжей, искалось просто слово, и возвращались те же значения, что и в этой функции? (чтобы также можно было воспользоваться ими, ну, допустим для замены текста на что то другое - для этого у меня уже есть функция).
Creat0Rта функция, визуально большая, и большие файлы обрабатывает довольно долго (доходит до 5-ти секунд). Смотри текст скрипта - у Sanja Alone дополнительно реализована нечувствительность к регистру для русского текста (для английского это выполняется автоматически), возможно поэтому он и работает медленнее...
вопрос в том, можно ли немного переделать эту функцию, чтобы вместо поиска дубляжей, искалось просто слово, и возвращались те же значения, что и в этой функции?м-да... подставь в функцию вместо "дубля" искомое "слово", и функция вернет "те же значения"... ;)
в чем разница-то?.. возвращаются всегда все значения, просто при замене использовались не все (смотри пределы):For $i = $Array[0][0] to 2 Step -1
...
Next
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")
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")
Убери (или измени) один, и будет ставить галку (если все параметры верные).
amel27
Есть ещё небольшой вопрос, также немного затрагивающий функцию поиска дубликатов...
Возможно ли сделать поиск по файлу на дубликаты, но заранее не знаяя вхождения? т.е нужно проверить все существующие строки в файле, и если хоть какая то из них имеет дубликат (именно по строке), то удалить все точно такие же строки, но оставив оригинал (для каждой такой найденной строки, произвести данную операцию - т.е удаление дубликатов найденных строк). Но, подвог (для меня) в том, что нужно удалить не именно те строки (их дубликаты), а те которые располагаются на три строчки выше.
Вот пример файла:
Первая строка
Ещё строка - > вот это и нужно чтобы удалилось (так как на три строки ниже, есть дубль той строки, которая на одну ниже этой (но её положение не фажно))
и ещё строка
просто текст
и ещё строка
и ещё больше текста
строка номер 7 - > и вот это нужно чтобы удалилось
строка 8
и текст строки номер 9
И ещё больше текста
P.S.
В данном случае, скорость обработки, не очень уж важно, да и визуализация тоже :) - Главное функционал!
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
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 (т.е она расположена на три строки выше чем совпавший дубль). Я пометил красным те строки, которые именно в этом куске, и должны будут быть удалены в конце обработки.
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
...... судя по файлу это больше смахивает на работу с блоками текста, чем просто со строками
amel27
просто добавь еще один IF:
Огромное THENX! - Как всё оказывается просто :)
судя по файлу это больше смахивает на работу с блоками текста, чем просто со строками
Ну да, просто содержимое этого файла, может доходить до 5-ти, а то и 10-ти ТЫСЯЧЬ! строк (иногда и больше) - и это всё закладки в браузере Opera (как избранное у IE), данная функция, позволит удалить в этом файле все дублирующиеся закладки. Просто если удалить у любого такого блока, строчку содержащюю #URL, то после запуска браузера, эта закладка не будет отображаться, и даже более этого, браузер сам всё “поправит” в файле, и “затрёт” оставшиеся строчки, которые для него, как бы являются “мусором”.
Creat0Rесли удалить у любого такого блока, строчку содержащюю #URL, то после запуска браузера, эта закладка не будет отображаться, и даже более этого, браузер сам всё “поправит” в файле, и “затрёт” оставшиеся строчкивсе это замечательно... но представь, что в блоке поменялись местами две строчки (подправит ли это браузер, это ведь не ошибка?), или в новой версии добавили новый реквизит... работа скрипта будет нарушена. Поэтому более "правильным" представляется следующий алгоритм:
- читаем файл и сразу нумеруем записи по блокам (а не по строкам);
- один из реквизитов (URL) оформляем как ключевой для блока;
- формируем новый файл ссылок (поверх старого), но уже без дублей.
З.Ы. обычно чем "правильней" алгоритм, тем он медленней
amel27
представь, что в блоке поменялись местами две строчки (подправит ли это браузер, это ведь не ошибка?)
Именно те строчки, которые в промежутке #URL и URL=ссылка, меняться местами не могут, и вообще, все строчки всегда присутствуют так, как это задуманно браузером, я пробовал убирать строки по разному, но браузер ставил так как ему нужно.
в новой версии добавили новый реквизит
Сомневаюсь я, что разработчики когда либо возьмутся за правку работы с закладками, в браузере и так много чего править нужно, и вещи куда серъёзней чем закладки :) (хотя предусмотреть такую функцию, как не позволения добовлять закладки повторно, они конечно должны были).
обычно чем "правильней" алгоритм, тем он медленней
Но мне скорость не очень важна, я конечно буду очень рад если будет более усовершенствованный скрипт :), но так как он выполняется сейчас, меня вполне устраивает. Ещё раз спасибо.
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
З.Ы. я ваще нудный... =)
amel27
лучше постановку задачи сделать совместными усилиями.
Ок, буду далее только с открытыми картами появляться :) - просто по какой то причине, мне всё время кажется, что этими самыми “сочинениями”, мне удастса лучше объяснить цель моей задачи.
применительно к твоему скрипту код можно еще укоротить:
Спасибо, но как оказалось, ты в каком то смысле был прав :( ...
Дело вот в чём, браузер не всегда затирает нужные закладки, иногда, если были удалены заглавы (#URL) двух закладок (блоков) идущих подряд, то он удаляет иногда и ту закладку которая идёт выше этих двух. Может всё же как то можно чтобы уже сразу весь блок удалять? :blush2:
я ваще нудный
Желаю чтобы все пользователи этого форума были такими нудными, я бы тогда здесь по жизннно зависал :) - и вообще, нет ли такой возможности (может тоже скрипт написать?), чтобы за каждое твоё оставленное сообщение (пусть даже по всему форуму), автоматом оно обозначалось бы как “Полезное сообщение” - оно так и есть :)
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
чтобы за каждое твоё оставленное сообщение (пусть даже по всему форуму), автоматом оно обозначалось бы как “Полезное сообщение” - оно так и есть не переживай - это пройдет... :)
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
Может есть способ покороче с этим бороться?
Вот на всякий пожарный, прикладываю файл, содержащий дубликаты таких (разных) блоков.
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
amel27
Удаляются не все дублирующиеся блоки :( - и как ни странно, не удалился дубль именно закладки этого поста :) (эксперементировал на прикреплённом мной раньше файле).
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.