Распарсить log файл

Помогите, пожалуйста, распарсить файл. Не могу придумать за что зацепится.

04.08.2024 06:41:14.775  Получено время 2447 Название устройства №2 04.08.2024 6:41:15 - синхронизация не требуется
04.08.2024 06:43:14.786  Получено время 22B3 Название устройства №3 04.08.2024 6:43:16 - время получения ответа превышает допуск
04.08.2024 11:47:01.967  Истекли попытки отправить запрос 234C Название устройства №4
05.08.2024 14:03:55.149  Получено время 2356 Название устройства №1 05.08.2024 14:03:57 - время получения ответа превышает допуск
05.08.2024 14:03:56.796  Получено время 2356 Название устройства №1 05.08.2024 14:03:58 - требуется синхронизация
05.08.2024 14:03:58.920  Установлена коррекция времени 2356 Название устройства №1
........

Нужно получить дату и время возникновения событий, id устройства (2447, 22B3, и т.д.), Название устройства, Событие (Получено время, Установлена коррекция времени, и. т.д. ну и остальное в комментарии)

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

Если есть у кого идеи, заранее спасибо


Ответы (2 шт):

Автор решения: Dyakov Alexander

Что-то понравилось мне в последнее время работать с классами. Возможно хардкод, но из той информации, которая предоставлена ничего лучше не придумал.

class parseddata {
    [string]$Date
    [string]$Time
    [string]$id
    [string]$Events
    [string]$Comment
    parseddata([string]$Line){
        $this.Date = $line.substring(0,10)
        $this.Time = $line.substring(11,13)
        $this.id = ([regex]::Match($line.substring(24,($line.Length-24)),"\d{2}(\d|\w){2}")).groups[0].value
        $this.Events = ([regex]::Match($line.substring(24,($line.Length-24)), "([А-я]+\s){2,4}")).groups[0].value
        $commentstart = 26+$($this.Events.Length)+$($this.id.Length)
        $this.Comment = $line.Substring($commentstart,($line.Length-$commentstart))
    }
}
$text = gc C:\tmp\test.log -Encoding UTF8
Foreach ($line in $text){
    [parseddata]::new($line)

}
→ Ссылка
Автор решения: Алексей Р

Можно разобрать с помощью одного регулярного выражения с именованными (для удобства) группами захвата:

$regex = '^(?<date>\d{2}\.\d{2}\.\d{4})\s(?<time>\d{2}:\d{2}:\d{2}\.\d{3})\s{2}(?<msg>.+?(?=\s\d))\s(?<id>.{4})\s(?<name>.+?(?=$|\d{2}\.))(?<comment>.*$)'
$arrayFromFile = Get-Content -Path 'c:\test\file5.txt' -Encoding UTF8 | `
ForEach-Object { if($_ -match $regex) { $Matches }}
$arrayFromFile

То же, с "ручным" выводом:

$regex = '^(?<date>\d{2}\.\d{2}\.\d{4})\s(?<time>\d{2}:\d{2}:\d{2}\.\d{3})\s{2}(?<msg>.+?(?=\s\d))\s(?<id>.{4})\s(?<name>.+?(?=$|\d{2}\.))(?<comment>.*$)'
$arrayFromFile = Get-Content -Path 'c:\test\file5.txt' -Encoding UTF8 | `
ForEach-Object { if($_ -match $regex) { $Matches }}
$counter = 0
$arrayFromFile | ForEach-Object { echo "`nСтрока $((++$counter)):" "Дата: $($_.date)" "Время: $($_.time)" "Сообщение: $($_.msg)" "ИД устройства: $($_.id)" "Имя устройства: $($_.name)" "Примечание: $($_.comment)" }
Строка 1:
Дата: 04.08.2024
Время: 06:41:14.775
Сообщение: Получено время
ИД устройства: 2447
Имя устройства: Название устройства №2
Примечание: 04.08.2024 6:41:15 - синхронизация не требуется

Строка 2:
Дата: 04.08.2024
Время: 06:43:14.786
Сообщение: Получено время
ИД устройства: 22B3
Имя устройства: Название устройства №3
Примечание: 04.08.2024 6:43:16 - время получения ответа превышает допуск

Строка 3:
Дата: 04.08.2024
Время: 11:47:01.967
Сообщение: Истекли попытки отправить запрос
ИД устройства: 234C
Имя устройства: Название устройства №4
Примечание:

Строка 4:
Дата: 05.08.2024
Время: 14:03:55.149
Сообщение: Получено время
ИД устройства: 2356
Имя устройства: Название устройства №1
Примечание: 05.08.2024 14:03:57 - время получения ответа превышает допуск

Строка 5:
Дата: 05.08.2024
Время: 14:03:56.796
Сообщение: Получено время
ИД устройства: 2356
Имя устройства: Название устройства №1
Примечание: 05.08.2024 14:03:58 - требуется синхронизация

Строка 6:
Дата: 05.08.2024
Время: 14:03:58.920
Сообщение: Установлена коррекция времени
ИД устройства: 2356
Имя устройства: Название устройства №1
Примечание:
→ Ссылка