Показать полную графическую версию : [решено] Работа с текстом (сравнить строки в файле)
sashadeg
11-02-2010, 15:59
Возможно вопрос покажется лёгким, но я не имею ни какова опыта с функциями обработки текста... ='(
Имеется вот такой текст в txt файле:
16:28:50 10.02.2010 188.17.248.182
16:53:43 10.02.2010 94.50.29.247
17:06:42 10.02.2010 188.17.247.185
17:38:12 10.02.2010 94.51.38.162
18:37:05 10.02.2010 188.17.236.44
18:52:17 10.02.2010 188.19.39.189
20:28:26 10.02.2010 94.50.21.39
20:47:19 10.02.2010 94.51.8.29
21:56:44 10.02.2010 94.50.20.178
22:05:33 10.02.2010 188.17.216.4
22:41:42 10.02.2010 88.205.187.204
00:14:43 11.02.2010 188.19.36.242
07:29:22 11.02.2010 90.151.234.113
07:42:37 11.02.2010 94.51.71.82
Задача. Нужно сравнить все IP адреса, и если будут одинаковые - отделить их как-нибудь, например записать в другой txt файл.
Вот у меня решение этой задачи встало на отделении первых 24 символов в строках (время и дата).
От одой строчки то я научился отделять, а вот если этих строк больше одной - то ступор.
Если формат файла именно такой, то можно воспользоваться следующим набором шаблонов
$sPath = @ScriptDir & '\log.txt'; положить рядом со скриптом файл с данными
$hFile = FileOpen($sPath, 0)
;$sText = '16:28:50 10.02.2010 188.17.248.182'
$sPattern_Time = '(\d\d:\d\d:\d\d)'; шаблон для вычленения времени
$sPattern_Date = '(\d\d\.\d\d\.\d\d\d\d)'; шаблон для вычленения даты
$sPattern_IP = '(\d+\.\d+\.\d+\.\d+)'; шаблон для вычленения IP
$sSum_allIP = ''; строка для хранения всех IP
$sSum_needIP = ''; строка для хранения повторяющихся IP
While 1
$sLine = FileReadLine($hFile); построчное считывание файла
If @error = -1 Then ExitLoop
$sTime = StringRegExpReplace($sLine, $sPattern_Time & '\s+' & $sPattern_Date & '\s+' & $sPattern_IP, '\1'); ищем время
$sDate = StringRegExpReplace($sLine, $sPattern_Time & '\s+' & $sPattern_Date & '\s+' & $sPattern_IP, '\2'); ищем дату
$sIP = StringRegExpReplace($sLine, $sPattern_Time & '\s+' & $sPattern_Date & '\s+' & $sPattern_IP, '\3'); ищем IP
If StringInStr($sSum_allIP, $sIP) Then; если есть повтор в IP
If Not StringInStr($sSum_needIP, $sIP) Then $sSum_needIP &= $sIP & '|'; и если мы ранее не занесли этот IP в список, то заносим
EndIf
$sSum_allIP &= $sIP & '|'; включаем новый IP в список
WEnd
$sResult = StringTrimRight($sSum_needIP, 1); убираем последний pipe (|) для красоты
If StringLen($sResult) = 0 Then
MsgBox(0, '', 'There no identical IPs'); нет повторяющихся IP
Else
MsgBox(0, '', $sResult); список повторяющихся IP разделенных pipe'ом (|)
EndIf
madmasles
11-02-2010, 18:02
У меня вот так, без StringRegExpReplace, получилось: #include <file.au3>
#include <Array.au3>
Dim $a_StringOne[1], $a_StringNoOne[1], $a_String
$sPathOld = @ScriptDir & '\log.txt'
$sPathOne = @ScriptDir & '\ОригинальныеIP.txt'
$sPathNoOne = @ScriptDir & '\ПовтряющиесяIP.txt'
FileOpen($sPathOld, 0)
FileOpen($sPathOne, 2)
FileOpen($sPathNoOne, 2)
_FileReadToArray($sPathOld, $a_String)
For $i = 1 To UBound($a_String) - 1
$s_StringIP = StringMid($a_String[$i], StringInStr(StringStripWS($a_String[$i], 2), _
" ", 1, -1) + 1, StringLen($a_String[$i]))
_ArraySearch($a_StringOne, $s_StringIP)
If @error = 6 Then
_ArrayAdd($a_StringOne, $s_StringIP)
FileWriteLine($sPathOne, $s_StringIP)
Else
_ArrayAdd($a_StringNoOne, $s_StringIP)
FileWriteLine($sPathNoOne, $s_StringIP)
EndIf
Next
$vIP_One = UBound($a_StringOne) - 1
$vIP_NoOne = UBound($a_StringNoOne) - 1
MsgBox(0, "", "Оригинальных IP: " & $vIP_One & @CRLF & "Повторяющихся IP: " & $vIP_NoOne)
_ArrayDisplay($a_StringOne, "Только оригинальные IP")
_ArrayDisplay($a_StringNoOne, "Эти IP повторяются")
Только не могу понять, надо в конце файлы закрывать или нет.
sashadeg
11-02-2010, 18:14
Спасибо большое и kaster и madmasles!!!
Оба скрипта очень хорошие!!! Прямо под меня =)
madmasles
1. у меня выходные файлы пусты
2. ипы повторяются на выходе. если в логфайле повторяющихся ипов 3, то на выходе будем иметь тоже 3 ипа, что не очень удобно, как мне кажется. лучше заносить по одному для каждого повтора.
madmasles
11-02-2010, 19:04
1. у меня выходные файлы пусты
2. ипы повторяются на выходе. если в логфайле повторяющихся ипов 3, то на выходе будем иметь тоже 3 ипа, что не очень удобно, как мне кажется. лучше заносить по одному для каждого повтора. » Насчет 1. не знаю, у меня в оба файла информация пишется.
2. Добавил проверку, чтобы в ПовтряющиесяIP.txt IP только по одному разу добавлялся. #include <file.au3>
#include <Array.au3>
Dim $a_StringOne[1], $a_StringNoOne[1], $a_String
$sPathOld = @ScriptDir & '\log.txt'
$sPathOne = @ScriptDir & '\ОригинальныеIP.txt'
$sPathNoOne = @ScriptDir & '\ПовтряющиесяIP.txt'
FileOpen($sPathOld, 0)
FileOpen($sPathOne, 2)
FileOpen($sPathNoOne, 2)
_FileReadToArray($sPathOld, $a_String)
For $i = 1 To UBound($a_String) - 1
$s_StringIP = StringMid($a_String[$i], StringInStr(StringStripWS($a_String[$i], 2), _
" ", 1, -1) + 1, StringLen($a_String[$i]))
_ArraySearch($a_StringOne, $s_StringIP)
If @error = 6 Then
_ArrayAdd($a_StringOne, $s_StringIP)
FileWriteLine($sPathOne, $s_StringIP)
Else
_ArraySearch($a_StringNoOne, $s_StringIP)
If @error = 6 Then
_ArrayAdd($a_StringNoOne, $s_StringIP)
FileWriteLine($sPathNoOne, $s_StringIP)
EndIf
EndIf
Next
$vIP_One = UBound($a_StringOne) - 1
$vIP_NoOne = UBound($a_StringNoOne) - 1
MsgBox(0, "", "Оригинальных IP: " & $vIP_One & @CRLF & "Повторяющихся IP: " & $vIP_NoOne)
_ArrayDisplay($a_StringOne, "Только оригинальные IP")
_ArrayDisplay($a_StringNoOne, "Эти IP повторяются")
sashadeg
11-02-2010, 19:59
madmasles
1. у меня выходные файлы пусты »
Хотел об этом написать, но лично мне это не помешало, и я промолчал. Но так то у меня тоже не пишет в файлы
madmasles
11-02-2010, 20:27
у меня тоже не пишет в файлы »
Еще раз проверил у себя - все пишет. Какая у Вас версия AutoIt? У меня 3.3.2.0.
Единственное, что приходит в голову, это заменить FileWriteLine($sPathOne, $s_StringIP)
....
FileWriteLine($sPathNoOne, $s_StringIP)
на FileWrite($sPathOne, $s_StringIP & @CRLF)
....
FileWrite($sPathNoOne, $s_StringIP & @CRLF)
А можно так :
#include <file.au3>
#include <Array.au3>
; Создание файла данных
If Not FileExists (@ScriptDir & '\' & 'Test1.dat') Then
$sStringList= '00:14:41 11.02.2010 188.19.36.242' & @CRLF & _
'11:14:41 05.02.2010 188.19.36.242' & @CRLF & _
'07:29:22 11.02.2010 90.151.234.113' & @CRLF & _
'07:42:37 11.02.2010 94.51.71.82' & @CRLF & _
'01:25:34 10.02.2010 94.51.71.82' & @CRLF
$file = FileOpen("Test1.dat", 1)
FileWrite ( $file, $sStringList )
FileClose($file)
EndIf
; Чтение из файла в строку
$file = FileOpen("Test1.dat", 0)
$sStr=FileRead ( $file , FileGetSize ( "Test.dat" ) )
MsgBox(0,'$sStr',$sStr)
;-Получение массива строк с совпавшими IP
Dim $aDouble[1]
For $i=1 To _FileCountLines("Test1.dat")
$sLine= FileReadLine ( $file, $i )
$sPattern='^\S+\s+\S+\s+(\S+)$'
$IP=StringRegExpReplace ( $sLine, $sPattern, "\1")
$sPattern='\n?.*' & $IP
$aArray=StringRegExp ( $sStr, $sPattern,3 )
If UBound($aArray) >1 Then
For $j=1 To UBound($aArray)-1
; Здесь можно произвести запись дублей в др. файл
_ArrayAdd($aDouble,$aArray[$j])
Next
EndIf
Next
FileClose($file)
_ArrayDisplay($aDouble,'$aDouble')
у меня выходные файлы пусты »
Но так то у меня тоже не пишет в файлы »
; Запись в файлы идет если :
$hFileOne=FileOpen($sPathOne, 2)
$hFileNoOne=FileOpen($sPathNoOne, 2)
FileWriteLine($hFileOne, $s_StringIP)
FileWriteLine($hFileNoOne, $s_StringIP)
а не :
FileWriteLine($sPathOne, $s_StringIP)
FileWriteLine($sPathNoOne, $s_StringIP)
gregaz, и о чем мне это должно сказать? :)
gregaz, и о чем мне это должно сказать? »
Насколько я понял у вас не шла запись в файлыю
madmasles
11-02-2010, 23:49
Но у меня же пишет все в файлы именно так:$sPathOne = @ScriptDir & '\ОригинальныеIP.txt'
$sPathNoOne = @ScriptDir & '\ПовторяющиесяIP.txt'
...
FileOpen($sPathOne, 2)
FileOpen($sPathNoOne, 2)
...
FileWriteLine($sPathOne, $s_StringIP)
...
FileWriteLine($sPathNoOne, $s_StringIP) Я никак не могу понять почему у Вас не пишет. Мистика какая-то.
У меня не писало ,после измения записало ???
madmasles
13-02-2010, 18:21
Если и так писать не будет, то я не знаю что делать.#include <file.au3>
#include <Array.au3>
Dim $a_StringOne[1], $a_StringNoOne[1], $a_String
$sPathOld = @ScriptDir & '\log.txt'
$sPathOne = @ScriptDir & '\ОригинальныеIP.txt'
$sPathNoOne = @ScriptDir & '\ПовторяющиесяIP.txt'
FileOpen($sPathOld, 0)
_FileReadToArray($sPathOld, $a_String)
For $i = 1 To UBound($a_String) - 1
$s_StringIP = StringMid($a_String[$i], StringInStr(StringStripWS($a_String[$i], 2), _
" ", 1, -1) + 1, StringLen($a_String[$i]))
_ArraySearch($a_StringOne, $s_StringIP)
If @error = 6 Then
_ArrayAdd($a_StringOne, $s_StringIP)
Else
_ArraySearch($a_StringNoOne, $s_StringIP)
If @error = 6 Then
_ArrayAdd($a_StringNoOne, $s_StringIP)
EndIf
EndIf
Next
$vIP_One = UBound($a_StringOne) - 1
$vIP_NoOne = UBound($a_StringNoOne) - 1
MsgBox(0, "", "Оригинальных IP: " & $vIP_One & @CRLF & "Повторяющихся IP: " & $vIP_NoOne)
FileOpen($sPathOne, 2)
FileOpen($sPathNoOne, 2)
_FileWriteFromArray($sPathOne, $a_StringOne, 1)
_FileWriteFromArray($sPathNoOne, $a_StringNoOne, 1)
_ArrayDisplay($a_StringOne, "Только оригинальные IP")
_ArrayDisplay($a_StringNoOne, "Эти IP повторяются")
Если и так писать не будет, то я не знаю что делать. »
У меня продолжает не писать.
Если изменить -то пишет.
Возможно это зависит от версии AutoIt ? ( У меня 3.3.4) - У тебя вроде 3.3.2 ( В 3.3.3 Уже вносились изменения в FileOpen().)
P.S.
Причем если писать вообще без предварительного открытия (FileOpen($sPathOne, 2),
прерасно пишет.
Такое впечатление , что такая запись (FileOpen($sPathOne, 2) уже заняла файл ,
и не позволяет туда писать через путь к файлу только через Хэндли открытия файла.
madmasles
14-02-2010, 00:45
gregaz,
Я на эту тему задал вопрос здесь: http://autoit-script.ru/index.php?topic=1134.msg8188;topicseen#new
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.