Author Topic: В продолжение темы по поиску строки в файле.  (Read 3499 times)

0 Members and 1 Guest are viewing this topic.

putman

  • Активный участник
  • ***
  • Posts: 199
    • View Profile
Здравствуйте.

Хочу вернуться к данной теме - http://crapware.aidf.org/forum/index.php?topic=1011.0, а именно, к быстрому поиску при помощи утилиты Find file.exe.
Тогда проблема была успешно решена, но сейчас требуется не просто получить ответ - есть искомая комбинация букв/цифр в файле или нет, но и узнать номер строки в которой она находится.

Может ли Find file.exe такое ?
Помогите пожалуйста.

putman

  • Активный участник
  • ***
  • Posts: 199
    • View Profile
Code: [Select]
UNDEFINE($url)
$ank = "aicauro"
$url = ""
$v1 = 7
INIWRITE("name.ini","file","name_small.txt")
$start = $_ms
INIWRITE("name.ini","ank",$ank)
INIWRITE("name.ini","return","-1")

EXECUTE("Find file.exe")
WHILE(INT(INIREAD("name.ini", "return")) = -1)
   WAITMS(30)
   //LOGWRITE ("Ждём")
END_CYC
IF(INT(INIREAD("name.ini", "return")) = 1)
   LOGWRITE ("Строка есть в базе")
END_IF

Я так понял, в ИНИ файле находится информация для поиска.
Параметр file указывает на файл, это понятно.
Параметр return тоже ясно, если строка найдена то он равен 1.
Параметр ank берёт искомую строку. Почему именно ank ? Я не нашел описания функций Find file.exe, только Find.exe, там про АНК ничего нет.
В описании Find.exe есть параметр N, если его указать при запуске, то вернётся номер строки, пробовал в наш ИНИ файл вставлять, не получается.

И как Find file.exe понимает, что данные лежат в name.ini и возвращать результат нужно туда ?

Помогите разобраться.
« Last Edit: November 29, 2017, 12:14:22 PM by putman »

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Здравствуйте.

Хочу вернуться к данной теме - http://crapware.aidf.org/forum/index.php?topic=1011.0, а именно, к быстрому поиску при помощи утилиты Find file.exe.
Тогда проблема была успешно решена, но сейчас требуется не просто получить ответ - есть искомая комбинация букв/цифр в файле или нет, но и узнать номер строки в которой она находится.

Может ли Find file.exe такое ?
Помогите пожалуйста.

пролистал ту тему. всегда, когда нужна была скорость поиска строки, шел другим путем, писал все строки в одну длинную. и в тестах Vinta есть такой пример, но он его почему то проигнорировал   :-\ . переписал его тесты на версию 4.12 . и добавил нумерацию подстрок в строке (только для теста №5).
Code: (clickermann) [Select]
#name "Работа с файлом"

// Для  v4.12


//==============================================================================
SUB (itog)    //  вывод затраченного времени
   $test_time = $_ms-$start
   LOGWRITE ("Время теста. Вариант ", $v1, "   ", $test_time, " мс")
   LOGWRITE (" ")
   LOGWRITE ("-------------------------------------------------")
END_SUB

//==============================================================================

LOGCLEAR


// тест 1 вариант 1  длинный адрес
$start = $_ms
$v1 = 1
for($var=0, $var < 10)
   $pos = 0
   $_ankf = TFRead("name.txt", $var+1)
   
   IF((STRPOS ($_ankf, "mail/") > 0) & ($pos = 0))
      $pos =  STRPOS($_ankf, "mail/") + 5
   END_IF
   
   IF((STRPOS($_ankf, "inbox/") > 0) & ($pos = 0))
      $pos =  STRPOS($_ankf, "inbox/") + 6
   END_IF
   
   IF((STRPOS($_ankf, "list/") > 0) & ($pos = 0))
      $pos =  STRPOS($_ankf, "list/") + 5
   END_IF
   
   IF((STRPOS($_ankf, "bk/") > 0) & ($pos = 0))
      $pos =  STRPOS($_ankf, "bk/") + 3
   END_IF
   
   $_ankf = STRCUT2($_ankf, $pos, 100)
   //LOGWRITE ($_ankf)
END_CYC
itog()
$test_time1 = $test_time


// тест 2 вариант 2  короткий адрес
UNDEFINE($url)
$start = $_ms
$v1 = 2
for($var=0, $var < 10)
   $url = TFRead("name.txt", $var+1)
   IF(STRPOS ($url, "mail/") > 0)
      $url = STRCUT2($url, STRPOS($url, "mail/")+5, 100)
   ELSE
      IF(STRPOS ($url, "inbox/") > 0)
         $url = STRCUT2($url, STRPOS($url, "inbox/")+6, 100)
      ELSE
         IF(STRPOS ($url, "list/") > 0)
            $url = STRCUT2($url, STRPOS($url, "list/")+5, 100)
         ELSE
            IF(STRPOS ($url, "bk/") > 0)
               $url = STRCUT2($url, STRPOS($url, "bk/")+3, 100)
            END_IF
         END_IF
      END_IF
   END_IF
   $url = STRCUT2($url, 1, STRPOS($url, "/")-1)
   
   //LOGWRITE ($url)
END_CYC
itog()
$test_time2 = $test_time


// тест 3  прямое сравнение длинных
UNDEFINE($url)
$ank = "http://my.mail.ru/mail/aicauro/"
$start = $_ms
$v1 = 3
for ($i=0, $i<TFCOUNT("name.txt"))
   $url = TFRead("name.txt", $i+1)
   IF($ank = $url)
      LOGWRITE ("Имя есть в базе")
   END_IF
end_cyc
itog()
$test_time3 = $test_time


// тест 4   прямое сравнение коротких
UNDEFINE($url)
$ank = "aicauro"
$start = $_ms
$v1 = 4
for ($i=0, $i<TFCOUNT("name_small.txt"))
   $url = TFRead("name_small.txt", $i+1)
   IF($ank = $url)
      LOGWRITE ("Имя есть в базе")
   END_IF
end_cyc
itog()
$test_time4 = $test_time



//////////////////////////////////
// тест 5   короткие в строку
UNDEFINE($url)
$ank = "aicauro"
//$ank ="31og5y"
$url = ""
$v1 = 5

$t_str = $_ms
for ($i=1, $i<TFCOUNT("name_small.txt")+1)
   
   $n_str = $i
   WHILE(STRLEN($n_str) < 5)
     $n_str = STRCONCAT("0",$n_str)
   END_CYC
   
   
   
   
   
   $url = STRCONCAT($url, TFRead("name_small.txt", $i),$n_str)
end_cyc
//print("на создание строки ушло ",$_ms - $t_str, " мс")
//LOGWRITE ("$url = ", $url)
//LOGWRITE ("Len ", STRLEN($url))



$start = $_ms
IF(STRPOS($url, $ank) > 0)
   LOGWRITE ("Имя есть в базе")
   
   print("номер строки - ", int(STRCUT2($url,STRPOS($url,$ank)+STRLEN($ank), STRPOS($url,$ank)+STRLEN($ank)+4)))
   
ELSE
   LOGWRITE ("Имени нет в базе")
END_IF
$url = STRCONCAT($url, $ank)
itog()
$test_time5 = $test_time
////////////////////////////////////

// тест 6   короткие в массив
UNDEFINE($url)
$ank = "aicauro"
$url = ""
$v1 = 6
for ($i=0, $i<TFCOUNT("name_small.txt"))
   $data = TFRead("name_small.txt", $i+1)
   ARRPUSH($url, $data)
end_cyc
//LOGWRITE ("ARRSIZE = ", ARRSIZE($url2))

$start = $_ms
for ($i=0, $i < ARRSIZE($url))
   IF($ank = $url[$i])
      LOGWRITE ("Имя есть в базе")
   END_IF
end_cyc
$url = ARRPUSH($url, $ank)
itog()
$test_time6 = $test_time


// тест 7   вызов AutoIt
UNDEFINE($url)
$ank = "aicauro"
$url = ""
$v1 = 7
INIWRITE("name.ini","file","name_small.txt")
$start = $_ms
INIWRITE("name.ini","ank",$ank)
INIWRITE("name.ini","return","-1")
EXECUTE("Find file.exe")
WHILE(INT(INIREAD("name.ini", "return")) = -1) // ожидание
   WAITMS(30)
   //LOGWRITE ("Ждём")
END_CYC
IF(INT(INIREAD("name.ini", "return")) = 1)
   LOGWRITE ("Имя есть в базе")
END_IF
itog()
$test_time7 = $test_time






WAIT(1)

LOGWRITE (" ")
LOGWRITE ("Время теста")
LOGWRITE ("Тест 1 ", $test_time1, " мс")
LOGWRITE ("Тест 2 ", $test_time2, " мс")
LOGWRITE (" ")
LOGWRITE ("Тест 3. Длинные ", $test_time3, " мс")
LOGWRITE ("Тест 4. Короткие ", $test_time4, " мс")
LOGWRITE ("Тест 5. Короткие в строку ", $test_time5, " мс")
LOGWRITE ("Тест 6. Короткие в массив ", $test_time6, " мс")
LOGWRITE ("Тест 7. Короткие. Вызов AutoIt ", $test_time7, " мс")

HALT

 лог:
Code: [Select]
11:58:47 Время теста. Вариант 1   13 мс
11:58:47 
11:58:47 -------------------------------------------------
11:58:47 Время теста. Вариант 2   10 мс
11:58:47 
11:58:47 -------------------------------------------------
11:58:49 Время теста. Вариант 3   1048 мс
11:58:49 
11:58:49 -------------------------------------------------
11:58:49 Имя есть в базе
11:58:49 Время теста. Вариант 4   818 мс
11:58:49 
11:58:49 -------------------------------------------------
11:58:52 Имя есть в базе
11:58:52 номер строки - 1000
11:58:52 Время теста. Вариант 5   8 мс
11:58:52 
11:58:52 -------------------------------------------------
11:58:53 Имя есть в базе
11:58:53 Время теста. Вариант 6   352 мс
11:58:53 
11:58:53 -------------------------------------------------
11:58:54 Имя есть в базе
11:58:54 Время теста. Вариант 7   35 мс
11:58:54 
11:58:54 -------------------------------------------------
11:58:55 
11:58:55 Время теста
11:58:55 Тест 1 13 мс
11:58:55 Тест 2 10 мс
11:58:55 
11:58:55 Тест 3. Длинные 1048 мс
11:58:55 Тест 4. Короткие 818 мс
11:58:55 Тест 5. Короткие в строку 8 мс
11:58:55 Тест 6. Короткие в массив 352 мс
11:58:55 Тест 7. Короткие. Вызов AutoIt 35 мс

как видите, поиск подстроки в длинной строке самый быстрый. есть ограничение для кликера - строка размером в 1мб, то есть 1 000 000 символов. если у тебя файл больше мегабайта, то делим эту мега строку на несколько.

тесты с файлами адресов и прочим во вложении

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile

Параметр ank берёт искомую строку. Почему именно ank ? Я не нашел описания функций Find file.exe, только Find.exe, там про АНК ничего нет.
В описании Find.exe есть параметр N, если его указать при запуске, то вернётся номер строки, пробовал в наш ИНИ файл вставлять, не получается.

И как Find file.exe понимает, что данные лежат в name.ini и возвращать результат нужно туда ?


да потому, что Find file.exe Vint сам написал  в автоите (скорее всего). а что за Find.exe, и откуда описание этой утилитки, я не нашел, да и не искал...
если у Vinta остались исходники "Find file", то передать через ини номер строки - минутное дело.

Quote
И как Find file.exe понимает, что данные лежат в name.ini и возвращать результат нужно туда ?
:-\
точно также, как и кликерман понимает, что данные придут в name.ini, и что можно менять нужные параметры в нем.

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
кстати вот начиная с этого сообщения http://crapware.aidf.org/forum/index.php?topic=1011.msg7125#msg7125 ,  как раз таки начали обьединять строки в длинную строку, вроде все получилось в итоге. и без сторонних утилит.

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Параметр ank берёт искомую строку. Почему именно ank ?
Сам назвал. "Анкета" наверное из задания.

И как Find file.exe понимает, что данные лежат в name.ini и возвращать результат нужно туда ?
Жёстко прописано имя.


да потому, что Find file.exe Vint сам написал  в автоите (скорее всего).
если у Vinta остались исходники "Find file", то передать через ини номер строки - минутное дело.

Оооо... это мегасложный скрипт  :D
Code: (php) [Select]
$file = IniRead("name.ini", "default", "file", "" )
$ank = IniRead("name.ini", "default", "ank", "")
$hFile = FileOpen(@ScriptDir &"\"& $file, 0)

;~ 1-й вариант
$sText = FileRead($hFile) ;Читаем файл
If StringInStr($sText, $ank) Then
;~ MsgBox(0,"","Есть")
IniWrite("name.ini", "default", "return", "1" )
FileClose($hFile)
Exit
EndIf
IniWrite("name.ini", "default", "return", "0" )
FileClose($hFile)
Exit


Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
пролистал ту тему. всегда, когда нужна была скорость поиска строки, шел другим путем, писал все строки в одну длинную. и в тестах Vinta есть такой пример, но он его почему то проигнорировал   :-\ .
Потому, что версия тогда была рабочая 4.8 (и тестовая альфа 4.9) где "ограничение на строку 256 симолов".
Длина строковой переменной max 256 символов.

Тест 5 - не удался из-за ограничения длины переменной в 4.8, пришлось пропустить


putman

  • Активный участник
  • ***
  • Posts: 199
    • View Profile
dramster, спасибо.
Изначально не придал этому значения.
Попробовал и со строкой кликер действительно работает чертовски быстро !
Возможно программа Find file.exe сможет быстрее, надо пробовать.
Чтение файла в массив, а далее поиск в цикле среди строк, занимал 300 мсек в среднем.  Всего 380 строк, долго как-то, целую миллисекунду на строчку тратит.

Сделал в файле всё одной строкой.
Считывание, поиск позиции и вырезание требуемого участка заняло 8 !!! ВОСЕМЬ миллисекунд, что в 37 раз быстрее. По 0.02 мсек на обработку одной строки.
Этот результат меня полностью устраивает.

В строке было около 13 000 символов. На всякий случай увеличил её до 130 000 (такого объёма в игре никогда не будет) и в этом случае никаких ошибок не возникло, время же обработки выросло кратно увеличению информации.

СПАСИБО !!!

Vint, Ваш вариант сейчас изучу.
« Last Edit: November 29, 2017, 03:14:36 PM by putman »

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Оооо... это мегасложный скрипт  :D
Code: (php) [Select]
$file = IniRead("name.ini", "default", "file", "" )
$ank = IniRead("name.ini", "default", "ank", "")
$hFile = FileOpen(@ScriptDir &"\"& $file, 0)

;~ 1-й вариант
$sText = FileRead($hFile) ;Читаем файл
If StringInStr($sText, $ank) Then
;~ MsgBox(0,"","Есть")
IniWrite("name.ini", "default", "return", "1" )
FileClose($hFile)
Exit
EndIf
IniWrite("name.ini", "default", "return", "0" )
FileClose($hFile)
Exit

а что, не мегасложный ?  :-\  :D

у меня на написание перебирания строк по очереди ушел гдето час, пока нашел нужные функции  ;D.  и почемуто уверен, что можно было это все сделать проще и выполнение должно быть быстрее.

Code: (php) [Select]
#include <File.au3>


$file = IniRead("name.ini", "default", "file", "" )
$ank = IniRead("name.ini", "default", "ank", "")


For $str = 1 To _FileCountLines (@ScriptDir &"\"& $file) Step 1
If FileReadLine (@ScriptDir &"\"& $file,$str ) = $ank Then
; MsgBox(0,"","Есть "&$str)
IniWrite("name.ini", "default", "return", "1" )
IniWrite("name.ini", "default", "n_str", $str )
Exit
EndIf
Next

IniWrite("name.ini", "default", "n_str", "0" )
IniWrite("name.ini", "default", "return", "0" )

Exit

а скорость почти таже что и через кликер через массив  ;D
Code: [Select]
15:16:35 Имя есть в базе
15:16:35 Номер строки - 1000
15:16:35 Время теста. Вариант 7   327 мс
15:16:35 
15:16:35 -------------------------------------------------
15:16:36 Тест 7. Короткие. Вызов AutoIt 327 мс

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
меня осенило, конечно помог сценарий Vinta из автоита  ;D .

Code: (clickermann) [Select]
$start = $_ms
STRWRITELN ("test.bat", "clip < name_small.txt", 1)  //помещаем содержимое файла в буфер обмена
EXECUTE ("test.bat")
waitms(40)      //без задержки не успевает :(

//print(FROMCLIP ())

//////////////////////////////////


$ank = "aicauro"
 
$url = FROMCLIP ()


IF(STRPOS($url, $ank) > 0)
   LOGWRITE ("Имя есть в базе")
ELSE
   LOGWRITE ("Имени нет в базе")
END_IF
print("Время выполнения - ",$_ms - $start, " мс")

////////////////////////////////////

halt

 1000 строк. на все про все уходит 48 мс, с учетом задержки в 40 мс. да, не смог обойтись без бат файла  :( . да и без задержки не успевает инфа в буфер влезть  :( .

насчет номера строки, так это если только при записи нумеровать каждую.



по началу думал как нибудь всунуть содержимое файла в переменную, буфер был бы свободен, надеялся что HTTPGET поможет
Code: (clickermann) [Select]
print(HTTPGET("file:///C:/name_small.txt"))не работает :(
« Last Edit: November 29, 2017, 04:52:50 PM by dramster »