none
Помогите с парсингом лог файла. RRS feed

  • Вопрос

  • Добрый день.

    Сстолкнулся с ситуацией, когда необходимо парсить лог, подскажите пожалуйста, как эту задачу выполнить, средствами Powershell.

    Задача заключается в следующем, есть лог файл следующего вида, (привел лишь одну строку лога):


    Его необходимо привести в следующее состояние:

    Таким образом надо, удалить начало строки (необходимо учесть что время постоянно меняется в начале строки), а линукс время 1487591498.925 привести к нормальному виду, и все выгрузить в .csv файл.

    Буду очень признателен за помощь, так как дело с парсингом имею в первые.




    • Изменено new guy 1 10 марта 2017 г. 14:50
    23 февраля 2017 г. 12:09

Ответы

  • Чтобы время не сканировать два раза попробуйте:

    [RegEx]::Replace("dffdsfdf 1487515560.823 dddddddd", '\d{10}\.\d{3}', {[System.DateTimeOffset]::FromUnixTimeSeconds($args[0].Value).datetime.tolocaltime()})


    Сазонов Илья

    https://isazonov.wordpress.com/


    5 апреля 2017 г. 8:20
    Модератор
  • Спасибо, буду ждать :)

    Вчера немного прихворал, но сегоня получилось поколупать данный вопрос

    Попробуйте вариант по типу такого

    $logsDir = "D:\Test\logs"
    
        $CnDes = Get-Content "$logsDir\AD.txt" | foreach {
            if ($_ -match '^(?''cn''[^\s]+)\s+[^\s]+\s+(?''des''[^\s]+)'){
                $cCN = $Matches['cn']
                $cDes = $Matches['des']
            }
            "$cCN;$cDes"
        } | ConvertFrom-Csv -Delimiter ';' -Header 'Hostname','Description'
    
        $IPCN = Get-Content "$logsDir\DHCP.txt"| foreach {
            if ($_ -match '^(?''ip''\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'){$cIP = $Matches['ip']}
            if ($_ -match '(?''cn''[^\s]+)$'){$cCN = $Matches['CN']}
            "$cIP;$($cCN -replace '([^\.])\..+','$1')"
        } | ConvertFrom-Csv -Delimiter ';' -Header 'IP','Hostname'
        
        $logContent = (get-content "$logsDir\syslog.txt")
         
        $IPCN | foreach {
            $Alias = ""
            $HN = $($_.Hostname)
            $Alias = ($CnDes | where {$_.Hostname -eq $HN}).Description
            if ($Alias){$replace = $Alias}
            else {$replace = $HN}
            $logContent = $logContent -replace " $($_.ip) ", " $replace "
        }
     
        $logContent = $logContent -replace '^\d{4}(-\d{2}){2} (\d{1,2}:){2}\d{1,2} user\.notice (\d{1,3}\.){3}\d{1,3} ' -split '\\n' 
    
        $logContentFinish = $logContent -split '`r`n' | foreach {
            if ($_ -match '^(?''UnixTime''\d{10}\.\d{3})'){
                 $UnixTime = $matches['UnixTime']
                 $_ -replace "^$UnixTime",$([System.DateTimeOffset]::FromUnixTimeSeconds($UnixTime).datetime.tolocaltime()) 
            }
            else {$_}
        } # End Foreach
    
        $logContentFinish | Set-Content "$logsDir\result2.txt"

    Прошлый скрипт на 600 МБ отрабатывал 3 часа 30 минут, 

    новый 17 минут


    The opinion expressed by me is not an official position of Microsoft


    • Изменено Vector BCOModerator 7 марта 2017 г. 19:04
    • Помечено в качестве ответа new guy 1 8 марта 2017 г. 20:26
    7 марта 2017 г. 19:04
    Модератор
  • Можно попробовать нечто такого плана 
    '^\d{4}(-\d{2}){2} (\d{1,2}:){2}\d{1,2} user\.notice (((\d{1,3}\.){3}\d{1,3})|(\D+)) '

    The opinion expressed by me is not an official position of Microsoft

    • Предложено в качестве ответа Vector BCOModerator 14 марта 2017 г. 6:16
    • Помечено в качестве ответа Vector BCOModerator 15 марта 2017 г. 6:30
    9 марта 2017 г. 9:14
    Модератор
  • $logsDir = "D:\Test\logs"
    
        $CnDes = Get-Content "$logsDir\AD.txt" | foreach {
            if ($_ -match '^(?''cn''[^\s]+)\s+[^\s]+\s+(?''des''[^\s]+)'){
                $cCN = $Matches['cn']
                $cDes = $Matches['des']
            }
            "$cCN;$cDes"
        } | ConvertFrom-Csv -Delimiter ';' -Header 'Hostname','Description'
    
        $IPCN = Get-Content "$logsDir\DHCP.txt"| foreach {
            if ($_ -match '^(?''ip''\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'){$cIP = $Matches['ip']}
            if ($_ -match '(?''cn''[^\s]+)$'){$cCN = $Matches['CN']}
            "$cIP;$($cCN -replace '([^\.])\..+','$1')"
        } | ConvertFrom-Csv -Delimiter ';' -Header 'IP','Hostname'
        
        $logContent = (get-content "$logsDir\syslog.txt")
         
        $IPCN | foreach {
            $Alias = ""
            $HN = $($_.Hostname)
            $Alias = ($CnDes | where {$_.Hostname -eq $HN}).Description
            if ($Alias){$replace = $Alias}
            else {$replace = $HN}
            $IP = $($_.ip)
            $logContent = $logContent -replace " ($ip (([^-])|(-[^ ]))+) - (.+)", " `$1 $replace `$5"
        }
     
        $logContent = $logContent -replace '^\d{4}(-\d{2}){2} (\d{1,2}:){2}\d{1,2} user\.notice (((\d{1,3}\.){3}\d{1,3})|(\D+)) ' -split '\\n' 
    
        $logContentFinish = $logContent -split '`r`n' | foreach {
            if ($_ -match '^(?''UnixTime''\d{10}\.\d{3})'){
                 $UnixTime = $matches['UnixTime']
                 $_ -replace "^$UnixTime",$([System.DateTimeOffset]::FromUnixTimeSeconds($UnixTime).datetime.tolocaltime()) 
            }
            else {$_}
        } # End Foreach
    
        $logContentFinish | Set-Content "$logsDir\result2.txt"

    Попробуйте как то так

    Время я не засекал но не должно быть намного дольше чем прошлый вариант


    The opinion expressed by me is not an official position of Microsoft

    • Предложено в качестве ответа Vector BCOModerator 17 апреля 2017 г. 8:54
    • Помечено в качестве ответа Vector BCOModerator 18 апреля 2017 г. 19:36
    5 апреля 2017 г. 5:45
    Модератор

Все ответы

  • PS C:\Windows> $content = (get-content C:\test.txt) -replace '^\d{4}(-\d{2}){2} (\d{1,2}:){2}\d{1,2} user\.notice (\d{1,3}\.){3}\d{1,3} ' -split '\\n'

    $content

    или сразу запись в новый лог

    PS C:\Windows> (get-content C:\test.txt) -replace '^\d{4}(-\d{2}){2} (\d{1,2}:){2}\d{1,2} user\.notice (\d{1,3}\.){3}\d{1,3} ' -split '\\n' | out-file  C:\result.txt -append

    Так же не совсем понятно что обозначают цифры после user.notice (user.notice 10.10.41.63 ) и какими они могут быть, сейчас выражение написано из предположения что это ip адресс, но если это не так выделенные фрагменты стоит подправить на

    (\d{2}\.){3}\d{2}


    Вариант с правкой времени в localtime из unixtime

    (get-content c:\test.txt) -replace '^\d{4}(-\d{2}){2} (\d{1,2}:){2}\d{1,2} user\.notice (\d{1,3}\.){3}\d{1,3} ' -split '\\n' | foreach {
        $_ -match '^(?''UnixTime''\d{10}\.\d{3})' | Out-Null
        $UnixTime = $matches['UnixTime']
        $_ -replace "^$UnixTime",$([System.DateTimeOffset]::FromUnixTimeSeconds($UnixTime).datetime.tolocaltime()) | out-File C:\Result.txt -append
    }





    23 февраля 2017 г. 12:22
    Модератор
  • Как то так:
    $CnDes = Get-Content C:\ComputernameDescription.txt
    (get-content C:\test.txt) -replace '^\d{4}(-\d{2}){2} (\d{1,2}:){2}\d{1,2} user\.notice (\d{2}\.){3}\d{2} ' -split '\\n' | foreach {
        $_ -match '^(?''UnixTime''\d{10}\.\d{3})' | Out-Null
        $UnixTime = $matches['UnixTime']
        $Str = $_ -replace "^$UnixTime",$([System.DateTimeOffset]::FromUnixTimeSeconds($UnixTime).datetime.tolocaltime()) 
        $Str -match '^(\d{2}/?){3}\d{2} (\d{2}:?){3}\s+\d{3}\s+(?''IP''([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])) '
        $IP = $Matches['IP']
        $ComputerName = ([System.Net.Dns]::GetHostByAddress($IP).HostName -split '\.')[0]
        if ($($CnDes | Select-String $ComputerName) -match '^\w+\s+(?''des''\w+)\s+\w+'){$DesStr = $matches['des']}
        else {$DesStr = $ComputerName}
        $Str -replace " $IP "," $DesStr " | out-File C:\Result.txt
    }


    The opinion expressed by me is not an official position of Microsoft

    24 февраля 2017 г. 10:32
    Модератор
  • Благодарю за помощь, к сожалению при отработке скрипт выводит ошибки:

    Exception calling "GetHostByAddress" with "1" argument(s): "Value cannot be null.
    Parameter name: address"
    At line:7 char:5
    +     $ComputerName = ([System.Net.Dns]::GetHostByAddress($IP).HostName -split '\. ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : ArgumentNullException

    Хотел так же уточнить, в вашем варианте командлет Get-content используется 2 раза, я предпологал что необходимо его использовать 3 раза, получается ведь что необходимо сравнивать 3 txt файла выгрузки: AD (computer-description), DHCP (ip-computer), Файл лога (время-ip-url)

    Пожалуйста поправьте если я ошибаюсь.

    24 февраля 2017 г. 11:27
  • Благодарю за помощь, к сожалению при отработке скрипт выводит ошибки:

    Exception calling "GetHostByAddress" with "1" argument(s): "Value cannot be null.
    Parameter name: address"
    At line:7 char:5
    +     $ComputerName = ([System.Net.Dns]::GetHostByAddress($IP).HostName -split '\. ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : ArgumentNullException

    Хотел так же уточнить, в вашем варианте командлет Get-content используется 2 раза, я предпологал что необходимо его использовать 3 раза, получается ведь что необходимо сравнивать 3 txt файла выгрузки: AD (computer-description), DHCP (ip-computer), Файл лога (время-ip-url)

    Пожалуйста поправьте если я ошибаюсь.

    $CnDes = Get-Content C:\ComputernameDescription.txt
    (get-content C:\test.txt) -replace '^\d{4}(-\d{2}){2} (\d{1,2}:){2}\d{1,2} user\.notice (\d{2}\.){3}\d{2} ' -split '\\n' | foreach {
        $_ -match '^(?''UnixTime''\d{10}\.\d{3})' | Out-Null
        $UnixTime = $matches['UnixTime']
        $Str = $_ -replace "^$UnixTime",$([System.DateTimeOffset]::FromUnixTimeSeconds($UnixTime).datetime.tolocaltime()) 
        if ($Str -match '^(\d{2}/?){3}\d{2} (\d{2}:?){3}\s+\d{3,6}\s+(?''IP''([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])) '){
    $IP = $Matches['IP']
    $ComputerName = ([System.Net.Dns]::GetHostByAddress($IP).HostName -split '\.')[0] if ($($CnDes | Select-String $ComputerName) -match '^\w+\s+(?''des''\w+)\s+\w+'){$DesStr = $matches['des']} else {$DesStr = $ComputerName} $Str -replace " $IP "," $DesStr " | out-File C:\Result. txt
    }
    Else {
     $Str | out-File C:\Result.txt
    } }

    Строка

    [System.Net.Dns]::GetHostByAddress($IP).HostName

    преобразует IP в HostName аналогично nslookup но без лишней требухи, 3 файла в качестве источника данных получается как то громоздковато + по вашему примеру выгрузки из dhcp не понятно что вы хотите от туда подставлять

    Среди нижеследующего не нашел Hostname\Computername

    172.26.40.42    - 255.255.255.0  - c4-7d-46-20-68-15   -19.02.2017 20:42:04    -D
    172.26.40.43    - 255.255.255.0  - 00-23-26-92-16-f8   -20.02.2017 2:35:07     -D
    172.26.40.44    - 255.255.255.0  - e4-7f-b2-10-c6-4e   -20.02.2017 7:00:10     -D
    172.26.40.45    - 255.255.255.0  - 00-23-26-92-06-d9   -20.02.2017 7:50:59     -D
    172.26.40.46    - 255.255.255.0  - 2c-d4-44-bb-f1-c3   -20.02.2017 5:36:39     -D


    The opinion expressed by me is not an official position of Microsoft

    24 февраля 2017 г. 11:59
    Модератор
  • Точно, прошу прощения, скопировал с ошибками, файл DHCP выглядит так:


    Таким образом, необходимо подставлять последний столбец с хостнейм.

    Скрипт, упорно выдает ошибку:

    Cannot index into a null array.
    At line:3 char:5
    +     $UnixTime = $matches['UnixTime']
    +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
        + FullyQualifiedErrorId : NullArray

    Exception calling "GetHostByAddress" with "1" argument(s): "The requested name is valid, but no data of the requested t
    ype was found"
    At line:7 char:9
    +         $ComputerName = ([System.Net.Dns]::GetHostByAddress($IP).HostName -split ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : SocketException




    • Изменено new guy 1 10 марта 2017 г. 14:51
    24 февраля 2017 г. 14:17
  • По всей видимости вы скармливаете не правильные параметры скрипту

    опубликуйте 3 файла на обменнике, например Onedrive или GoogleDrive


    The opinion expressed by me is not an official position of Microsoft

    24 февраля 2017 г. 14:35
    Модератор
  • Получилось очень медленно и ресурсо затратно но вроде работает:

    $logsDir = "D:\Test\logs" $CnDes = Get-Content "$logsDir\AD.txt" | foreach { if ($_ -match '^(?''cn''[^\s]+)\s+[^\s]+\s+(?''des''[^\s]+)'){ $cCN = $Matches['cn'] $cDes = $Matches['des'] } "$cCN;$cDes" } | ConvertFrom-Csv -Delimiter ';' -Header 'Hostname','Description' $IPCN = Get-Content "$logsDir\DHCP.txt"| foreach { if ($_ -match '^(?''ip''\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'){$cIP = $Matches['ip']} if ($_ -match '(?''cn''[^\s]+)$'){$cCN = $Matches['CN']} "$cIP;$cCN" } | ConvertFrom-Csv -Delimiter ';' -Header 'IP','Hostname' (get-content "$logsDir\syslog.txt") -split '\r\n' | foreach { $_ -replace '^\d{4}(-\d{2}){2} (\d{1,2}:){2}\d{1,2} user\.notice (\d{1,3}\.){3}\d{1,3} ' -split '\\n'| foreach { if ($_ -match '^(?''UnixTime''\d{10}\.\d{3})'){ $UnixTime = $matches['UnixTime'] $Str = $_ -replace "^$UnixTime",$([System.DateTimeOffset]::FromUnixTimeSeconds($UnixTime).datetime.tolocaltime()) if ($Str -match '^(\d{2}/?){3}\d{2} (\d{2}:?){3}\s+\d+\s+(?''IP''([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])) '){ $IP = $Matches['IP'] $Hostname = ($IPCN | where {$_.ip -eq $IP}).hostname if (! ([string]::IsNullOrEmpty($Hostname))){ $Description = ($CnDes | where {$_.Hostname -eq $($Hostname -replace '([^\.]+)\..*','$1')}).Description if (! ([string]::IsNullOrEmpty($Description))){ $Str -replace " $IP "," $Description " | out-File "$logsDir\Result.txt" -append } else { $Str -replace " $IP "," $Hostname " | out-File "$logsDir\Result.txt" -append } } # End If (Hostname found) Else { $Str | out-File "$logsDir\Result.txt" -append } # End Else (Hostname not found) } # End If (IP Address found) else { $Str | out-File "$logsDir\Result.txt" -append } # End Else (IP Address not found) } # End If (Unix Time found and converted) else { $_ | out-File "$logsDir\Result.txt" -append } # End Else (Unix Time not found)

    Clear-Variable IP, Hostname, Description, matches -ErrorAction SilentlyContinue } # End Foreach (Syslog SubStrings) } # End Foreach (Syslog Strings)

    Есть чувство что можно сократить раза в 2, но среди ночи соображаю не лучшим образом.

    Пример отработки из ваших примеров видно на скрине:

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

    У меня расположение файлов "D:\Test\logs" прописано в первой строке, названия сохранены


    The opinion expressed by me is not an official position of Microsoft


    • Изменено Vector BCOModerator 27 февраля 2017 г. 1:10 Добавил Clear-Variable
    • Помечено в качестве ответа new guy 1 27 февраля 2017 г. 11:37
    • Снята пометка об ответе new guy 1 8 марта 2017 г. 20:26
    27 февраля 2017 г. 0:42
    Модератор
  • По идее можно просто переделать под

    [IO.File]::OpenText($path)

    Это должно дать прирост процентов на 40

    http://stackoverflow.com/questions/4192072/how-to-process-a-file-in-powershell-line-by-line-as-a-stream

    буду дома попробую переписать и потестировать


    The opinion expressed by me is not an official position of Microsoft

    3 марта 2017 г. 14:26
    Модератор
  • Добрый день, Vector BCO.

    Удалось ли Вам протестировать, ваше предположение ? :)

    6 марта 2017 г. 8:35
  • К сожалению выходные выдались очень загруженными и я не успел проверить предположение. Постараюсь проверить сегодня вечером.

    'asd123-1' -match "^((\w|\d){1,100})"
    $matches[0]
    
    # Result
    asd123


    The opinion expressed by me is not an official position of Microsoft

    6 марта 2017 г. 9:02
    Модератор
  • Спасибо, буду ждать :)
    6 марта 2017 г. 11:36
  • Спасибо, буду ждать :)

    Вчера немного прихворал, но сегоня получилось поколупать данный вопрос

    Попробуйте вариант по типу такого

    $logsDir = "D:\Test\logs"
    
        $CnDes = Get-Content "$logsDir\AD.txt" | foreach {
            if ($_ -match '^(?''cn''[^\s]+)\s+[^\s]+\s+(?''des''[^\s]+)'){
                $cCN = $Matches['cn']
                $cDes = $Matches['des']
            }
            "$cCN;$cDes"
        } | ConvertFrom-Csv -Delimiter ';' -Header 'Hostname','Description'
    
        $IPCN = Get-Content "$logsDir\DHCP.txt"| foreach {
            if ($_ -match '^(?''ip''\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'){$cIP = $Matches['ip']}
            if ($_ -match '(?''cn''[^\s]+)$'){$cCN = $Matches['CN']}
            "$cIP;$($cCN -replace '([^\.])\..+','$1')"
        } | ConvertFrom-Csv -Delimiter ';' -Header 'IP','Hostname'
        
        $logContent = (get-content "$logsDir\syslog.txt")
         
        $IPCN | foreach {
            $Alias = ""
            $HN = $($_.Hostname)
            $Alias = ($CnDes | where {$_.Hostname -eq $HN}).Description
            if ($Alias){$replace = $Alias}
            else {$replace = $HN}
            $logContent = $logContent -replace " $($_.ip) ", " $replace "
        }
     
        $logContent = $logContent -replace '^\d{4}(-\d{2}){2} (\d{1,2}:){2}\d{1,2} user\.notice (\d{1,3}\.){3}\d{1,3} ' -split '\\n' 
    
        $logContentFinish = $logContent -split '`r`n' | foreach {
            if ($_ -match '^(?''UnixTime''\d{10}\.\d{3})'){
                 $UnixTime = $matches['UnixTime']
                 $_ -replace "^$UnixTime",$([System.DateTimeOffset]::FromUnixTimeSeconds($UnixTime).datetime.tolocaltime()) 
            }
            else {$_}
        } # End Foreach
    
        $logContentFinish | Set-Content "$logsDir\result2.txt"

    Прошлый скрипт на 600 МБ отрабатывал 3 часа 30 минут, 

    новый 17 минут


    The opinion expressed by me is not an official position of Microsoft


    • Изменено Vector BCOModerator 7 марта 2017 г. 19:04
    • Помечено в качестве ответа new guy 1 8 марта 2017 г. 20:26
    7 марта 2017 г. 19:04
    Модератор
  • 8 марта 2017 г. 17:54
    Модератор
  • Доброй ночи, Vector BCO.

    Спасибо большое, ураа, это то что было необходимо, Вы так сильно помогли, данный вариант, работает ооочень быстро. Спасибо большое!!!

    Я только не учел один момент, что после user.notice, может быть так же и текст, пример:

    Подскажите пожалуйста, что необходимо изменить после:

    user\.notice (\d{1,3}\.){3}\d{1,3}

    8 марта 2017 г. 20:26
  • Можно попробовать нечто такого плана 
    '^\d{4}(-\d{2}){2} (\d{1,2}:){2}\d{1,2} user\.notice (((\d{1,3}\.){3}\d{1,3})|(\D+)) '

    The opinion expressed by me is not an official position of Microsoft

    • Предложено в качестве ответа Vector BCOModerator 14 марта 2017 г. 6:16
    • Помечено в качестве ответа Vector BCOModerator 15 марта 2017 г. 6:30
    9 марта 2017 г. 9:14
    Модератор
  • Здравствуйте, Vector BCO.

    Вероятно, я вас уже замучил :), но подскажите пожалуйста если вас не затруднит.

    Хочу изменить режим замены IP на Description, а именно чтобы IP оставался на прежнем месте, а Description заменял знак " - " , показал на картинке ниже, первая строка как выглядит вывод строки на данный момент, остальные как планируется, подскажите пожалуйста как это реализовать.

    23 марта 2017 г. 8:23
  • Вопрос ваш увидел, но есть большое подозрение что опять просядет время

    Попробую решить вопрос на выходных, так как на работе нет тестовых файлов и скачать их тоже возможности нет


    The opinion expressed by me is not an official position of Microsoft

    24 марта 2017 г. 8:49
    Модератор
  • Доброе утро, Vector BCO.

    Я предпологаю, что необходимо сравнивать файл, как-нибудь так:

    foreach {
    	if ($_ -match "^\d+\.\d+\s+\d+\s(?<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})") {$_ = $_ -replace " - ", " $replace "}
    	$syslognew += $_
    }


    27 марта 2017 г. 7:25
  • Добрый вечер, Vector BCO.

    Удалось ли Вам посмотреть, возможную реализацию ? :)

    28 марта 2017 г. 13:30
  • Попробовать не получилось, очень загруженная неделю включая выходные выдалась

    Реализаций возможно 2:

    1) поиск через Foreach по указанному IP и замена "-" на описание, по реализации это просто но работать будет долго (возможно очень), то что вы написали в сообщение выше похоже на данный концепт, но работать такие конструкции не будут :(

    2) Вариант с более сложным регулярным выражением и более сложной заменой. Работать должно быстро, но для того что бы это завелось нужно сесть и попробовать (к сожалению пока не вышло)

    Если вопрос срочный можно попробовать создать новый вопрос со ссылкой на это обсуждение, возможно Вам помогут другие участники форума например Kazun или ILYA [ sie ] Sazonov


    The opinion expressed by me is not an official position of Microsoft



    28 марта 2017 г. 14:08
    Модератор
  • Добрый день, Vector BCO.

    Нет, вопрос терпит, подожду вашего ответа :) Благодарю ! 

    29 марта 2017 г. 7:46
  • $logsDir = "D:\Test\logs"
    
        $CnDes = Get-Content "$logsDir\AD.txt" | foreach {
            if ($_ -match '^(?''cn''[^\s]+)\s+[^\s]+\s+(?''des''[^\s]+)'){
                $cCN = $Matches['cn']
                $cDes = $Matches['des']
            }
            "$cCN;$cDes"
        } | ConvertFrom-Csv -Delimiter ';' -Header 'Hostname','Description'
    
        $IPCN = Get-Content "$logsDir\DHCP.txt"| foreach {
            if ($_ -match '^(?''ip''\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'){$cIP = $Matches['ip']}
            if ($_ -match '(?''cn''[^\s]+)$'){$cCN = $Matches['CN']}
            "$cIP;$($cCN -replace '([^\.])\..+','$1')"
        } | ConvertFrom-Csv -Delimiter ';' -Header 'IP','Hostname'
        
        $logContent = (get-content "$logsDir\syslog.txt")
         
        $IPCN | foreach {
            $Alias = ""
            $HN = $($_.Hostname)
            $Alias = ($CnDes | where {$_.Hostname -eq $HN}).Description
            if ($Alias){$replace = $Alias}
            else {$replace = $HN}
            $IP = $($_.ip)
            $logContent = $logContent -replace " ($ip (([^-])|(-[^ ]))+) - (.+)", " `$1 $replace `$5"
        }
     
        $logContent = $logContent -replace '^\d{4}(-\d{2}){2} (\d{1,2}:){2}\d{1,2} user\.notice (((\d{1,3}\.){3}\d{1,3})|(\D+)) ' -split '\\n' 
    
        $logContentFinish = $logContent -split '`r`n' | foreach {
            if ($_ -match '^(?''UnixTime''\d{10}\.\d{3})'){
                 $UnixTime = $matches['UnixTime']
                 $_ -replace "^$UnixTime",$([System.DateTimeOffset]::FromUnixTimeSeconds($UnixTime).datetime.tolocaltime()) 
            }
            else {$_}
        } # End Foreach
    
        $logContentFinish | Set-Content "$logsDir\result2.txt"

    Попробуйте как то так

    Время я не засекал но не должно быть намного дольше чем прошлый вариант


    The opinion expressed by me is not an official position of Microsoft

    • Предложено в качестве ответа Vector BCOModerator 17 апреля 2017 г. 8:54
    • Помечено в качестве ответа Vector BCOModerator 18 апреля 2017 г. 19:36
    5 апреля 2017 г. 5:45
    Модератор
  • По времени у меня получилось ~ 18 минут, что в принципе похоже на предыдущий результат

    Самым продолжительным блоком является преобразование времени ~ 13 минут, что правда я не проверил результат (руки не дошли)


    The opinion expressed by me is not an official position of Microsoft

    5 апреля 2017 г. 7:55
    Модератор
  • Чтобы время не сканировать два раза попробуйте:

    [RegEx]::Replace("dffdsfdf 1487515560.823 dddddddd", '\d{10}\.\d{3}', {[System.DateTimeOffset]::FromUnixTimeSeconds($args[0].Value).datetime.tolocaltime()})


    Сазонов Илья

    https://isazonov.wordpress.com/


    5 апреля 2017 г. 8:20
    Модератор
  • Чтобы время не сканировать два раза попробуйте:

    [RegEx]::Replace("dffdsfdf 1487515560.823 dddddddd", '\d{10}\.\d{3}', {[System.DateTimeOffset]::FromUnixTimeSeconds($args[0].Value).datetime.tolocaltime()})

    Выглядит очень перспективно и на этом можно нормально сэкономить время

        $logContentFinish = $logContent -split '`r`n' | foreach {
            [RegEx]::Replace("$($_)",'^\d{10}\.\d{3}',$([System.DateTimeOffset]::FromUnixTimeSeconds($args[0].Value).datetime.tolocaltime()})
        } # End Foreach



    The opinion expressed by me is not an official position of Microsoft

    • Предложено в качестве ответа Vector BCOModerator 17 апреля 2017 г. 8:54
    5 апреля 2017 г. 12:51
    Модератор
  • Спасибо Большое !
    14 апреля 2017 г. 5:39