Powershell-如何从基于文本的日志文件中选择一个文本块,该文件在日志文件条目中带有时间戳 [英] Powershell - How to select a block of text from a text based log file that has a time stamp in the log file entry

查看:101
本文介绍了Powershell-如何从基于文本的日志文件中选择一个文本块,该文件在日志文件条目中带有时间戳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很抱歉,如果标题不太清楚,我想我的问题之一就是我想不出一种方法来清楚地描述我要达到的目标,但这并没有帮助我在谷歌搜索" 中可能有帮助的任何事情.

Sorry if the Title isn't very clear, I think part of my issue is I can't think of a way to clearly describe what I am trying to acheive, which has not helped me in 'Googling' anything that may be of help.

我正在尝试创建一个通用的脚本/函数,我可以传递两个时间值,一个开始时间和一个结束时间,以输出这两个时间戳之间的所有日志文件条目.这将成为脚本的核心部分,该脚本可从每天通常超过1GB的日志文件中提取非常小的时间跨度的日志文件条目,并且很难在文件查看器或编辑器中高效地进行操作,因此要花费大量时间从中提取相关的dta,目的是为开发人员提供数据以帮助调查问题.

I am trying to create a generic script / function that I can pass 2 time values, a start time and an end time that will output all log file entries between these 2 time stamps. This will become the core part of a script to extract very small time spans of log file entries from logfiles that often exceed 1GB a day and are very difficult to manipulate in file viewers or editors efficiently and therefore take significant time to extract relevant dta from, for the purpose of providing developers with data to aid investigations into problems.

日志文件具有不同的格式,但是大多数遵循以下通用格式:

The log files are of differing formats but most of these follow the general format below:

2418 22:19:58: CTracker::ReadAvlPackets - ENTER ...
b18 22:19:58: SICInterfaceApp::ListenerRead: Qtype < 15> Subtype < 27> #8597208 From <¸i`      > 
b18 22:19:58: CTracker::OnListenerRead - PktPrc: 0x00000001
2418 22:20:00: cAvlComIMobile::GetData  - ErrSev: 0x00000000 
2418 22:20:02: cAvlComIMobile::GetData  - ErrSev: 0x00000000 

我已经创建了一个基本功能:

I have created a basic function:

function Get-LogExtract ($StartTime){
$Log = "path-to-log-file"
Get-Content $Log | 
ForEach-Object {
    $parts = $_ -split ' '
    if ($parts[1] -eq $StartTime) {
            $_
        }
    }
}

如果我使用以下命令行运行它

which if I run it using the following command line

Get-LogExtract 22:19:58:

它将仅输出时间戳为22:19:58的日志文件行:在这一行中,这是我最初想要实现的目标,但是从那时起,要求已扩大.

it will output only the logfile lines that have the timestamp of 22:19:58: in the line, which is fine, it was what I initally wanted to acheive, but since this point the requirement has expanded.

我现在想要做的是提供一个开始时间和一个结束时间,并在这些输出之间包含所有行.

What I now want to be able to do is to provide a start time and an end time and have all lines between these output.

我试图实现一个do while循环来做到这一点,但是由于我无法实现我要达到的目标,因此很麻烦.

I have tried to implement a do while loop to do this but was obvioulsy not getting anywhere as I couldn't acheive the goal I am trying to reach.

所以我有几个问题.

    1. is there a better way to tackle what I am trying to acheive?
    2. if not, how can I implement a loop to acheive my goal?


更新代码:


Updated Code:

好的,因此这是下面PSGuy所建议的经过调整的代码段,该代码段适用于每行都有时间戳记条目的日志文件.

OK, so here's a code segment tweaked as advised by PSGuy below, which works a treat with logfiles that have a time stamp entry on every line.:

function Get-LogExtract ($StartTime, $EndTime) {
$Log = "path-to-log-file"
Get-Content $Log | 
    ForEach {
    $parts = $_ -split ' '
        if ($parts[1] -ge $StartTime -and $parts[1] -le $EndTime) {
            $_
        }
    }
}

推荐答案

您可以在此处执行几项操作.首先是,如果您想要一个真正的日期时间对象,则可以运行System.DateTime类的以下静态方法:

There are a few things you can do here. The first is, if you want a true date-time object, then you can run the following static method of the System.DateTime class:

[DateTime]::Parse($Time) # 22:19:58 == Friday, September 19, 2014 10:19:58 PM

您还可以进行字符串比较,因为针对字符串的任何比较运算符都会通过Char值来评估每个字符,因此"22:19:59" -gt"22:19:58"为true.

You can also do string comparisons, because any comparison operator against a string will evaluate each character by Char value, so "22:19:59" -gt "22:19:58" is true.

我认为转换为DateTime格式对您来说会更容易,但是,进行简单的字符串比较就可以了.像这样:

I think that converting to a DateTime format will be easier for you, however, doing a simple string comparison will work. Something like:

如果$ line [$ I] -ge"22:19:59"-和$ line [$ I] -le"23:59:59"理论上可以在您建议的脚本/函数中使用.我也建议做一个for循环来逐步浏览日志文件的每一行,但是,这不是必需的.如果我没有在管线中使用实际的对象,那么我就不会喜欢foreach-object cmdlet,在该管线中我可以针对对象本身调用静态方法.在这里,这只是简单的字符串工作,我个人会使用for循环,但这全都是优先选择的问题. for构造看起来像这样:

If $line[$I] -ge "22:19:59" -and $line[$I] -le "23:59:59" will theoretically work in your proposed script / function. I would also recommend doing a for loop to step through each line of the log file, however, it's not required. I'm not a big fan of the foreach-object cmdlet if I'm not using actual objects in the pipleline, where I can call a static method against the object itself. Here, it's just simple string work, and I would personally use a for loop, but it's all a matter of preference. The for construct would look like this:

$logFile = Get-Content myLogFile.log # or whatever file format, it's an input arg anyway
for ($I = 0; $I -le $logFile.GetUpperBound(""); $I++)
{
    $logFile[$I] # reads the line; you can assign a variable at this point
}

foreach循环也可以工作.我个人喜欢使用for,但是foreach实际上是同一回事. foreach等效项是:

A foreach loop would also work. I personally like using for, but foreach is effectively the same thing. The foreach equivalent is:

foreach ($line in $logFile)
{
    $line # perform whatever split operations you want to perform
}

请告诉我们是否可行!

这篇关于Powershell-如何从基于文本的日志文件中选择一个文本块,该文件在日志文件条目中带有时间戳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆