Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   [решено] Работа с текстом (сравнить строки в файле) (http://forum.oszone.net/showthread.php?t=167060)

sashadeg 11-02-2010 15:59 1344780

Работа с текстом (сравнить строки в файле)
 
Возможно вопрос покажется лёгким, но я не имею ни какова опыта с функциями обработки текста... ='(

Имеется вот такой текст в 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 символов в строках (время и дата).
От одой строчки то я научился отделять, а вот если этих строк больше одной - то ступор.

kaster 11-02-2010 16:52 1344825

Если формат файла именно такой, то можно воспользоваться следующим набором шаблонов
Код:

$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 1344858

У меня вот так, без 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 1344869

Спасибо большое и kaster и madmasles!!!

Оба скрипта очень хорошие!!! Прямо под меня =)

kaster 11-02-2010 18:26 1344882

madmasles
1. у меня выходные файлы пусты
2. ипы повторяются на выходе. если в логфайле повторяющихся ипов 3, то на выходе будем иметь тоже 3 ипа, что не очень удобно, как мне кажется. лучше заносить по одному для каждого повтора.

madmasles 11-02-2010 19:04 1344910

Цитата:

Цитата kaster
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 1344954

Цитата:

Цитата kaster
madmasles
1. у меня выходные файлы пусты »

Хотел об этом написать, но лично мне это не помешало, и я промолчал. Но так то у меня тоже не пишет в файлы

madmasles 11-02-2010 20:27 1344977

Цитата:

Цитата sashadeg
у меня тоже не пишет в файлы »

Еще раз проверил у себя - все пишет. Какая у Вас версия AutoIt? У меня 3.3.2.0.
Единственное, что приходит в голову, это заменить
Код:

FileWriteLine($sPathOne, $s_StringIP)
....
FileWriteLine($sPathNoOne, $s_StringIP)

на
Код:

FileWrite($sPathOne, $s_StringIP & @CRLF)
....
FileWrite($sPathNoOne, $s_StringIP & @CRLF)


gregaz 11-02-2010 20:42 1344983

А можно так :
Код:

#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')


gregaz 11-02-2010 23:08 1345014

Цитата:

Цитата kaster
у меня выходные файлы пусты »

Цитата:

Цитата sashadeg
Но так то у меня тоже не пишет в файлы »

; Запись в файлы идет если :
Код:

$hFileOne=FileOpen($sPathOne, 2)
$hFileNoOne=FileOpen($sPathNoOne, 2)
 
FileWriteLine($hFileOne, $s_StringIP)
FileWriteLine($hFileNoOne, $s_StringIP)

а не :
Код:

FileWriteLine($sPathOne, $s_StringIP)
 FileWriteLine($sPathNoOne, $s_StringIP)


kaster 11-02-2010 23:13 1345017

gregaz, и о чем мне это должно сказать? :)

gregaz 11-02-2010 23:17 1345021

Цитата:

Цитата kaster
gregaz, и о чем мне это должно сказать? »

Насколько я понял у вас не шла запись в файлыю

madmasles 11-02-2010 23:49 1345053

Но у меня же пишет все в файлы именно так:
Код:

$sPathOne = @ScriptDir & '\ОригинальныеIP.txt'
$sPathNoOne = @ScriptDir & '\ПовторяющиесяIP.txt'
...
FileOpen($sPathOne, 2)
FileOpen($sPathNoOne, 2)
...
FileWriteLine($sPathOne, $s_StringIP)
...
FileWriteLine($sPathNoOne, $s_StringIP)

Я никак не могу понять почему у Вас не пишет. Мистика какая-то.

gregaz 12-02-2010 00:15 1345066

У меня не писало ,после измения записало ???

madmasles 13-02-2010 18:21 1346320

Если и так писать не будет, то я не знаю что делать.
Код:

#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 повторяются")


gregaz 13-02-2010 22:23 1346514

Цитата:

Цитата madmasles
Если и так писать не будет, то я не знаю что делать. »

У меня продолжает не писать.
Если изменить -то пишет.
Возможно это зависит от версии 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 1346594

gregaz,
Я на эту тему задал вопрос здесь: http://autoit-script.ru/index.php?to...;topicseen#new


Время: 07:00.

Время: 07:00.
© OSzone.net 2001-