简体   繁体   English

解析文本文件中的多行

[英]Parse multiple lines in text file

How can I parse this text1.txt: 我如何解析此text1.txt:

2016-04-06 12:02:32 AM - INFO  – Connected to services
2016-04-06 12:02:47 AM - ERROR – Service exception
System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: Pooled connection request timed out (Fault Detail is equal to An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
Oracle.ManagedDataAccess.Client.OracleException: Pooled connection request timed out
at OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, String affinityInstanceName, Boolean bForceMatch)
at OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, String affinityInstanceName, Boolean bForceMatch)
at OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword)
at Oracle.ManagedDataAccess.Client.OracleConnection.Open()
2016-04-06 12:02:47 AM - WARN  – Unexpected error has occurred. See application logs for more details. Service will wait for 60 seconds and then try again.
2016-04-06 12:07:07 AM - INFO  – Connected to services
2016-04-06 12:07:22 AM - ERROR – Service exception
System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: Pooled connection request timed out (Fault Detail is equal to An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
Oracle.ManagedDataAccess.Client.OracleException: Pooled connection request timed out
at OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, String affinityInstanceName, Boolean bForceMatch)
at OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, String affinityInstanceName, Boolean bForceMatch)
at OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword)
at Oracle.ManagedDataAccess.Client.OracleConnection.Open()
2016-04-06 12:07:22 AM - WARN  – Unexpected error has occurred. See application logs for more details. Service will wait for 60 seconds and then try again.

This is my current code: 这是我当前的代码:

function parse-log
{
    param(
        [string]$line
    )

    $data = $line.split(' ') 
    $dateString = '{0} {1} {2}' -f $data[0], $data[1], $data[2]
    $timeStamp = Get-Date -Date $dateString
    [pscustomobject]@{
        TimeStamp = $timeStamp
        Client    = $data[3]
        Message   = $data[4]
    }
}

foreach ( $line2 in $lines2 )
{
    $entry = parse-log -line $line2
}

I get errors because it's trying to parse the next line. 我收到错误消息,因为它试图解析下一行。 I need it to parse the next datetime. 我需要它来解析下一个日期时间。 In addition, how can I split at hyphens ( - ) so I get the following? 此外,如何分割连字符( - ),以获得以下内容?

$timestamp = 2016-04-06 12:02:32 AM
$data[3] = INFO or ERROR
$data[4] = the rest of the string

If you just want to process lines starting with a date and skip over the other lines, you could do something like this: 如果您只想处理以日期开头的行并跳过其他行,则可以执行以下操作:

$pattern = '^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [AP]M) - (\w+) +– (.*)'
$lines2 | Where-Object { $_ -match $pattern } | ForEach-Object {
    [PSCustomObject]@{
        TimeStamp = $matches[0]
        Severity  = $matches[1]
        Message   = $matches[2]
    }
}

Note that the second dash is not a hyphen, but an en-dash (character U+2013). 请注意,第二个破折号不是连字符,而是一个破折号(字符U + 2013)。

I would recommend you to use a regex to parse the log: 我建议您使用正则表达式来解析日志:

(\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\s\w{2})\s-\s(\w+)\s+–\s(.+?)(?=\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\s\w{2}\s-\s|$)

Demo 演示

And here the script: 这是脚本:

$content = Get-Content "PATH_TO_YOUR_LOG" -Encoding UTF8

$regex = '(?si)(\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\s\w{2})\s-\s(\w+)\s+–\s(.+?)(?=\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\s\w{2}\s-\s|$)'

$entries = [regex]::Matches($content, $regex)

foreach ($entry in $entries)
{
    [PSCustomObject]@{
        TimeStamp =  $entry.Groups[1].Value
        Level  = $entry.Groups[2].Value
        Message   =  $entry.Groups[3].Value
    }
}

Output: 输出:

TimeStamp              Level Message                                                                                                                                                       
---------              ----- -------                                                                                                                                                       
2016-04-06 12:02:32 AM INFO  Connected to services                                                                                                                                         
2016-04-06 12:02:47 AM ERROR Service exception System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: Pooled connection request timed out (Fault Detail is equal to ...
2016-04-06 12:02:47 AM WARN  Unexpected error has occurred. See application logs for more details. Service will wait for 60 seconds and then try again.                                    
2016-04-06 12:07:07 AM INFO  Connected to services                                                                                                                                         
2016-04-06 12:07:22 AM ERROR Service exception System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: Pooled connection request timed out (Fault Detail is equal to ...
2016-04-06 12:07:22 AM WARN  Unexpected error has occurred. See application logs for more details. Service will wait for 60 seconds and then try again.  

A perhaps more direct example using the switch statement which was patterned (to some extent) after AWK. 一个使用switch语句的也许更直接的示例,该语句在AWK之后(在某种程度上)被模式化。

# Switch statement loops over each line in the file
switch -regex (get-content data.txt)
{
    # Makes sure that the line matches
    '^[0-9]+-[0-9]+-[0-9]' {
        # split the line with multiple assignement & type constraint
        [datetime] $timestamp, $data1, $data2 = $_ -split ' . '
        # Build the result object
        [PSCustomObject] @{
            timestamp = $timestamp
            data1 = $data1
            data2 = $data2
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM