2013-09-26 5 views
1

Я пытаюсь использовать AutoIt для изучения текстового файла и вывода строк выбора в CSV. Проблема, с которой я сталкиваюсь, заключается в том, что она берет навсегда. Текущий метод анализирует только одну строку за раз. Он может гореть через 5-10 строк в секунду, но я ищу что-то намного быстрее в рамках AutoIt.Более быстрый способ изучения текста в AutoIt?

Код:

#include <File.au3> 
$xnConfirm = False 
$xnConfirmMsg = 0 
while $xnConfirm = False 

     $xnFile = FileOpenDialog("File to Examine...","%userprofile%","All (*.*)") ;InputBox("File???", "Which file do you want to review?","C:\") 
    If FileExists($xnFile) = True Then 
      $xnConfirm = True 
     Else 
       $xnConfirmMsg = msgbox(1,"File Not Found...",$xnFile & " does not exist." & @crlf & "Please select another file.") 
     EndIf 
WEnd 

$xnConfirm = False 
$xnConfirmMsg = 0 
while $xnConfirm = False 
    $xnTargetFile = FileOpenDialog("Location to Save to...",$xnFile & " - output.csv","All (*.*)");"%userprofile%\Documents\output.csv" 
        ;FileSaveDialog("Location to Save to...","%userprofile%","All (*.*)",16,"output - " & $xnFile & " - output.csv") ; 
     Consolewrite("Outputting to " & $xnTargetFile & @crlf) 

     if fileexists($xnTargetFile) then 
      $xnConfirmMsg = msgbox(4,"Overwrite?","Are you sure you want to overwrite " & @crlf & $xnTargetFile) 

       if $xnConfirmMsg = 6 Then 
        $xnConfirm = True 
        filedelete($xnTargetFile)    
       EndIf 
      Else 

       $xnConfirm = True 

     EndIf  
WEnd 

progresson("Line count","Verifying the number of lines in " & $xnFile) 
$xnFileLine = _FileCountLines($xnFile) ;InputBox("Number of lines","How many lines are in this document?",10000) 
consolewrite("Loading "& $xnFile & " with " & $xnFileLine & " total lines." & @crlf) 
progressoff() 

local $hfl = FileOpen($xnFile,0) 
FileWrite($xnTargetFile,"") 
FileOpen($xnTargetFile, 1) 

$i = 1 

ProgressOn("Creating CSV","Extracting matching data.","",0,0,16) 
$xnTargetLine = 1 

FileWriteLine($xnTargetFile,"Timestamp,Message,Category,Priority,EventId,Severity,Title,Machine,App Domain,ProcessID,Process Name,Thread Name,Win32 ThreadId") 

While $i < $xnFileLine 

        ;$xnCurrentLine = FileReadLine($xnFile,$i) ;Old Settings 
      $xnCurrentLine = FileReadLine($hfl,$i) 
      ;MsgBox(1,"",$xnCurrentLine) 

     Select 
     Case stringinstr($xnCurrentLine,"Timestamp:") 
      $xnTargetLine = stringmid($xnCurrentLine,12,stringlen($xnCurrentLine) - 12 + 1) & "," 
     Case stringinstr($xnCurrentLine,"Message:") 
      $xnTargetLine = $xnTargetLine & stringmid($xnCurrentLine,10,stringlen($xnCurrentLine) - 10 + 1) & "," 
     Case stringinstr($xnCurrentLine,"Category:") 
      $xnTargetLine = $xnTargetLine & stringmid($xnCurrentLine,11,stringlen($xnCurrentLine) - 11 + 1) & "," 
     Case stringinstr($xnCurrentLine,"Win32 ThreadId:") 
      $xnTargetLine = $xnTargetLine & stringmid($xnCurrentLine,16,stringlen($xnCurrentLine) - 16 + 1) & @crlf 
       FileWriteLine($xnTargetFile,$xnTargetLine) 
     case Else 
       consolewrite("Nothing on line " & $i & @crlf) 
     EndSelect 
     $i = $i + 1 
        ProgressSet(round($i/$xnFileLine * 100,1),$i & " of " & $xnFileLine & " lines examined." & @cr & "Thank you for your patience.") 
    WEnd 
ProgressOff() 

Для решения вопроса о том, что это делает, я читаю файл журнала, похожий на журнал трассировки. Я хочу, чтобы события выводились в CSV, чтобы я мог анализировать тенденции. Формат в файле журнала выглядит так:

Timestamp: 9/26/2013 3:33:23 AM 

Message: Log Event Received 

Category: Transaction 

Win32 ThreadId:2872 

Я знаю, что это формат кода, но я надеюсь, что его легче читать.

+0

Добавлено Snippit из файла журнала это означает для чтения/переформатировать. – Xenoranger

+0

и каков должен быть выход? (ive editet мой пост. работает ли это так?) – Teifun2

ответ

2

Я не уверен, было бы действительно быстрее, но вы могли бы использовать Regexp. Если бы вы могли сказать мне немного больше, что правила здесь:

  Case stringinstr($xnCurrentLine,"Timestamp:") 
     $xnTargetLine = stringmid($xnCurrentLine,12,stringlen($xnCurrentLine) - 12 + 1) & "," 
    Case stringinstr($xnCurrentLine,"Message:") 
     $xnTargetLine = $xnTargetLine & stringmid($xnCurrentLine,10,stringlen($xnCurrentLine) - 10 + 1) & "," 
    Case stringinstr($xnCurrentLine,"Category:") 
     $xnTargetLine = $xnTargetLine & stringmid($xnCurrentLine,11,stringlen($xnCurrentLine) - 11 + 1) & "," 
    Case stringinstr($xnCurrentLine,"Win32 ThreadId:") 
     $xnTargetLine = $xnTargetLine & stringmid($xnCurrentLine,16,stringlen($xnCurrentLine) - 16 + 1) & @crlf 
      FileWriteLine($xnTargetFile,$xnTargetLine) 
    case Else 
      consolewrite("Nothing on line " & $i & @crlf) 

и если вы могли бы дать мне 2 или 3 примера линии я мог бы попытаться сделать вас, функцию Regexp которым я думаю, будет много Быстрее.

Редактировать:

Я сделал пример сценария. Если входной файл выглядит примерно так:

Timestamp: 9/26/2013 3:33:23 AM 
Message: Log Event Received 
Category: Transaction 
Win32 ThreadId:2872 

Затем этот скрипт работает нормально

#include <Array.au3> 
Local $file = FileOpen("InputFile.txt", 0) 
$sText = FileRead($file) 
$aSnippets = StringRegExp($sText,"(?:Timestamp:|Message:|Category:|Win32 ThreadId:)(?:)?(.+)",3) 
_ArrayDisplay($aSnippets) 

Результатом является массив, содержащий следующие вещи:

[0] = 9/26/2013 3:33:23 AM 
[1] = Log Event Received 
[2] = Transaction 
[3] = 2872 
etc. 

Если вы хотите чтобы объединить эти 4 строки в одном, попробуйте использовать цикл for (если хотите, я могу сделать вам один)

Для 100 Линии Требуется 0.490570878768441 Miliseconds хранить каждое значение в одном массиве.

2

(Я хотел бы добавить комментарий с просьбой для выборки из данных, прочитанных в, однако у меня нет достаточно очков, все же ...)

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

Что-то вроде:

$outputFileData = "" 
$inputFileData = _FileReadToArray($xnFile) 

For $Counter = 1 to $inputFileData[0] 

     $tmpLine = $inputFileData[$Counter] 

     Select 

     Case stringinstr($tmpLine,"Timestamp:") 
      $outputFileData = stringmid($tmpLine,12,stringlen($tmpLine) - 12 + 1) & "," 

     Case stringinstr($tmpLine,"Message:") 
      $outputFileData &= stringmid($tmpLine,10,stringlen($tmpLine) - 10 + 1) & "," 

     Case stringinstr($xnCurrentLine,"Category:") 
      $outputFileData &= stringmid($tmpLine,11,stringlen($tmpLine) - 11 + 1) & "," 

     Case stringinstr($xnCurrentLine,"Win32 ThreadId:") 
      $outputFileData &= stringmid($tmpLine,16,stringlen($tmpLine) - 16 + 1) & @CRLF 

     case Else 
       ConsoleWrite("Nothing on line " & $i & @crlf) 

     EndSelect 

Next 

FileWriteLine($xnTargetFile, $outputFileData) 

(Пожалуйста, обратите внимание, я не включал проверку на наличие ошибок при этом я не проверить его на наличие ошибок :)

0

Существует Иным возможно идея.

Вы можете скопировать входной файл, переименовать его, а затем удалить из него все данные Useles. Это было бы очень легко с RegularExpressions и, вероятно, даже быстрее.

Если вы показать мне пример входного файла и как Выходной файл должен выглядеть как я мог бы попробовать :)

Смежные вопросы