Что нового

[Данные, строки] Выборка из текстового файла строк и сложение некоторых строк

exHalfer

Новичок
Сообщения
12
Репутация
0
Версия AutoIt: 3.3.8.1

Описание:
Есть текстовый файл вида
Код:
Включено 1-го 08:29 8 Вася работа Проект лист2
Открыта карта D:\Files\Obu4enie\Ucheb2
Выключено 1-го 08:29 нестандартный выход
Включено 1-го 08:29 8 Вася работа Проект лист2
Открыта карта D:\Files\Obu4enie\Ucheb2
Пауза 7 мин с 08:55
Выключено 1-го 09:12 2320 нажатий мыши
Включено 1-го 09:15 11 Макс работа Проект лист2
Открыта карта D:\Files\Obu4enie\Ucheb2
Пауза 5 мин с 10:27
Пауза 6 мин с 10:59
Выключено 1-го 13:15 6811 нажатий мыши
Включено 1-го 14:20 11 Макс работа Проект лист4
Открыта карта D:\Number\Obuchenie\Ucheb4
Выключено 1-го 14:24 546 нажатий мыши
Включено 1-го 14:38 16 Антон работа Проект лист4
Открыта карта D:\Number\Obuchenie\Ucheb4
Пауза 18 мин с 14:30
Пауза 6 мин с 15:08
Пауза 6 мин с 15:14
Выключено 1-го 16:01 1646 нажатий мыши

Где в строке Включено 1-го 08:29 8 Вася работа Проект лист2 - "8" - иднтификационный номер
Структура строк не меняется. Т.е. ИН всегда будет 4 подстрокой.

Необходимо записать в другой текстовый файл:
Время первого включения
Время выключения перед сменой номера
Сумма всех пауз до строки смены номера

Время включения после первой смены номера
Время выключения перед очередной сменой номера (либо последняя строка)
Сумма пауз после первой смены номера

Пример:
Код:
Включено 1-го 08:29 8 Вася работа Проект лист2
Выключено 1-го 09:12 2320 нажатий мыши
Общее время паузы 7 мин

Включено 1-го 09:15 11 Макс работа Проект лист2
Выключено 1-го 14:24 546 нажатий мыши
Общее время паузы 11 мин

Включено 1-го 14:38 16 Антон работа Проект лист4
Выключено 1-го 16:01 1646 нажатий мыши
Общее время паузы 30 мин

Примечания:
Пока я смог только убрать мусор из файла и посчитать общее время паузы.
Файл приобретает вид:
Код:
Включено 1-го 08:29 8 Вася работа Проект лист2
Включено 1-го 08:29 8 Вася работа Проект лист2
Включено 1-го 09:15 11 Макс работа Проект лист2
Включено 1-го 14:20 11 Макс работа Проект лист4
Включено 1-го 14:38 16 Антон работа Проект лист4

Общее время паузы: 48 мин

Сам код наработок:
Код:
FileDelete("log.txt")

;~ Строки для поиска
$OneSe = 'Включено'
$TwoSe = 'Пауза'
$TriSe = 'Выключено'

;~ Исходный файл
$file = FileRead('text.txt')

$Line = StringSplit($file, @CRLF, 1)

For $i = 1 To $Line[0] Step +1
;~    Все включения в лог файл
	  If StringInStr($Line[$i], $OneSe) Then 
		 FileWriteLine("log.txt", $Line[$i])
	  EndIf
;~ 	  Все паузы во временный файл
	  If StringInStr($Line[$i], $TwoSe) Then 
		 FileWriteLine("temp.txt", $Line[$i])
	  EndIf
;~ 	  Все выключения в лог файл
;~ 	  If StringInStr($Line[$i], $TriSe) Then 
;~ 		 FileWriteLine("log.txt", $Line[$i])
;~ 	  EndIf
Next
   


;~ Считаем общее время паузы из временного файла
$vTFile = FileOpen("temp.txt")
$vTmp = FileRead($vTFile)
$aTmp = StringRegExp($vTmp, '\h(\d+?)\h', 3)
If @error Then Exit 13
$vTmp = 0
For $i = 0 To UBound($aTmp) - 1
    $vTmp += $aTmp[$i]
Next
$aTmp = 0

;~ Записываем паузы в лог файл
FileWriteLine("log.txt","")
FileWriteLine("log.txt",'Общее время паузы: ' & $vTmp & ' мин')
FileDelete("temp.txt")

Код на запись строк выключения закомментирован, посчитал, что это бесполезно в таком виде.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Да, не простой лог вам попался, кто его делал явно не рассчитывал на то, что лог когда нибудь понадобиться парсить.
Вопрос, выключение, например, 1 -го, всегда предшествует включению 1 -го, или может быть такая ситуация. Включение...1, Включение...2, выключение...1, выключение 2?
 
Автор
E

exHalfer

Новичок
Сообщения
12
Репутация
0
Предшествует всегда (можно использовать предыдущий номер строки, перед сменой пользователя), но вот общая систематизация у меня вызывает головокружение уже :stars:
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Код:
$sData = FileRead('1.txt')
$aDataBlocks = StringRegExp($sData,'(?si)Включено\s*\d+.*?Выключено[^\r\n]+',3)
If Not IsArray($aDataBlocks) Then Exit 99
For $aRow In $aDataBlocks
	$aOn = StringRegExp($aRow,'(?si)(?=Включено)[^\r\n]+',1)
	$aOff = StringRegExp($aRow,'(?si)(?=Выключено)[^\r\n]+',1)
	$aPauses = StringRegExp($aRow,'(?sim)^Пауза\s*(\d+)',3)
	If IsArray($aOn) Then
		ConsoleWrite($aOn[0] & @LF)
	EndIf
	If IsArray($aOff) Then
		ConsoleWrite($aOff[0] & @LF)
	EndIf
	$iSumm = 0
	If IsArray($aPauses) Then

		For $vP in $aPauses
			$iSumm+=$vP
		Next
	EndIf
	ConsoleWrite('Общее время паузы: '& $iSumm& @LF)
	ConsoleWrite('---' & @LF)
Next


очень быстро, возможна оптимизация. В файле 1.txt ваш верхний пример.
 
Автор
E

exHalfer

Новичок
Сообщения
12
Репутация
0
Добился практически того, чего хотел. Кроме время выхода, но оно не так и важно уже. Код получился таким:
Код:
#include<Array.au3>

;~ Открываем файл для чтения и задаем нужные переменные
$mFile = FileOpen($CmdLineRaw)
$file = $CmdLineRaw
$temp = "logtemp.sblib"
$result = "!result.log"

;~ Удаляем старые временные файлы
FileDelete($temp)
FileDelete("tmp.sblib")

;~ Вывод ошибки, при отсутствии параметров командной строки
if $CmdLineRaw = @error Then
   MsgBox (4096, "Ошибка!", "Не верно задан параметр командной строки" & @CR & @CR & $CmdLineRaw)
   Exit
EndIf

;~ Начало учета пользователей
$pUser = 0

;~ Читаем весь файл и создаем блок для сканирования
$sData = FileRead($file)
$aDataBlocks = StringRegExp($sData,'(?si)Включено\s*\d+.*?Выключено[^\r\n]+',3)
If Not IsArray($aDataBlocks) Then Exit 99
;~ Считываем каждый блок отдельно, записывваем во временный файл
For $aRow In $aDataBlocks
    $aOn = StringRegExp($aRow,'(?si)(?=Включено)[^\r\n]+',1)
    $aOff = StringRegExp($aRow,'(?si)(?=Выключено)[^\r\n]+',1)
    $aPauses = StringRegExp($aRow,'(?sim)^Пауза\s*(\d+)',3)
;~ Устанавливаем текущее значение пользователя
	$aUser = StringSplit($aOn[0]," ")
;~ Запись во временный файл, если сменился пользователь
	If IsArray($aOn) Then
	  If $aUser[4] <> $pUser Then
		 ConsoleWrite($aOn[0] & @LF)
		 FileWriteLine($temp, $aOn[0])
	  EndIf
    EndIf
    If IsArray($aOff) Then
	  If $aUser[4] <> $pUser Then
		 ConsoleWrite($aOff[0] & @LF)
		 FileWriteLine($temp, $aOff[0])
	  EndIf
    EndIf
;~ Считаем для каждого блока сумму паузы
    $iSumm = 0
    If IsArray($aPauses) Then
        For $vP in $aPauses
            $iSumm+=$vP
        Next
    EndIf
	FileWriteLine($temp, 'Пауза '& $iSumm &' мин')
	$pUser = $aUser[4]
 Next
 
;~  Считываем временный файл и разбиваем по блокам
 $nData = FileRead($temp)
 $nDataBlocks = StringRegExp($nData,'(?si)Выключено\s*\d.*?Включено[^\r\n]+',3)
 $One = FileReadLine($temp, 1)
 $Last = FileReadLine($temp, -1)

;~ Если блоки создать не получилось (не было вторичных входов в систему)
 If Not IsArray($nDataBlocks) Then 

;~ Считываем все строки файла с паузами
While 1
$line = FileReadLine($mFile)
If @error = -1 Then ExitLoop
;~ Записываем все строки паузы во временный файл
$sString=$line
$sPattern = '^\s*(Пауза.*)\s*$'
$sRezult = StringRegExpReplace ( $sString ,$sPattern,'\1')
If @extended <> 0 Then 
FileWriteLine("tmp.sblib", $sString)
EndIf
WEnd

;~ Считаем общее время паузы
$vTFile = FileOpen("tmp.sblib")
$vTmp = FileRead($vTFile)
$aTmp = StringRegExp($vTmp, '\h(\d+?)\h', 3)
If @error Then Exit 13
$vTmp = 0
For $i = 0 To UBound($aTmp) - 1
    $vTmp += $aTmp[$i]
Next
$aTmp = 0

;~ Записываем все в файл результата и выходим
   FileWriteLine($result, 'Данные из ' & $CmdLineRaw & ':')
   FileWriteLine($result, '---')
   FileWriteLine($result, $One)
   FileWriteLine($result, "Пауза " & $vTmp & " мин")
   FileWriteLine($result, "==============================")
;~ Дописываем в конец файла общее время паузы
   FileWriteLine($file, "")
   FileWriteLine($file, "==============================")
   FileWriteLine($file, "Пауза " & $vTmp & " мин")
   FileDelete($temp)
   FileDelete("tmp.sblib")
   Exit
EndIf

;~ Если блоки успешно созданы записываем нужные строки
   FileWriteLine($result, 'Данные из ' & $CmdLineRaw & ':')
   FileWriteLine($result, '---')
   FileWriteLine($result, $One)
;~ Дописываем в конеЦ файла общее время паузы
   FileWriteLine($file, "")
   FileWriteLine($file, "==============================")
   FileWriteLine($file, $One)
	
;~ Если блоки успешно созданы считаем паузы в блоках
 For $nRow In $nDataBlocks
   $nOn = StringRegExp($nRow,'(?si)(?=Включено)[^\r\n]+',1)
   $nOff = StringRegExp($nRow,'(?si)(?=Выключено)[^\r\n]+',1)
   $nPauses = StringRegExp($nRow,'(?sim)^Пауза\s*(\d+)',3)

   $niSumm = 0
   For $nvP in $nPauses
	  $niSumm+=$nvP
   Next

;~ Записываем получивниеся суммы в файл результата
   FileWriteLine($result, 'Пауза '& $niSumm &' мин')
   FileWriteLine($result, "---")
   FileWriteLine($result, $nOn[0])
;~ Дописываем в конеЦ файла общее время паузы
   FileWriteLine($file, 'Пауза '& $niSumm &' мин')
   FileWriteLine($file, "---")
   FileWriteLine($file, $nOn[0])
  Next

;~ Дописываем последнюю строку (последняя пауза
  FileWriteLine($result, $Last)
  FileWriteLine($result, "==============================")
;~ Дописываем в конеЦ файла общее время паузы
  FileWriteLine($file, $Last)
  FileWriteLine($file, "==============================")
  
;~ Удаляем временные файлы
  FileDelete($temp)

Большое спасибо inververs за помощь :beer:
 
Верх