2013-02-03 35 views
0

我有帶時間戳的日誌文件。即使第一個時間標記或最後一個時間標記不存在,我也想使用sed在兩個時間戳之間搜索文本。 例如,如果我在9:30和9:40之間搜索,那麼即使9:30和9:40都不存在,但時間戳在9:30和9:40之間,它也應該返回文本。使用sed在兩個時間幀之間搜索文本

我使用的是sed一個襯墊:

sed -n '/7:30:/,/7:35:/p' xyz.log 

但是,只有當兩個時間戳存在返回的數據;如果其中一個時間戳丟失,它將打印所有內容。如果時間爲12小時格式,它將爲AM和PM提取數據。

此外,我有不同的時間戳格式爲不同的日誌文件,所以我需要一個通用的命令。

這裏有一些時間格式的例子:

<Jan 27, 2013 12:57:16 AM MST> 

Jan 29, 2013 8:58:12 AM 

2013-01-31 06:44:04,883 

其中一些包含AM/PM即12小時格式和其他包含24小時格式,所以我必須考慮到這一點。

我也一樣試過,但它不工作:

sed -n -e '/^2012-07-19 18:22:48/,/2012-07-23 22:39:52/p' history.log 
+0

請在這裏搜索StackOverflow爲您的答案。這個問題每週都會被詢問和回答。祝你好運。 – shellter

+0

@shellter如果經常被問到,也許你可以產生一個副本,所以我們可以正確關閉這個問題? –

回答

1

隨着你解析時間格式的嚴重混合泳,sed沒有使用正確的工具。我會自動接觸Perl,但是Python也會這樣做,如果你把它放在心上,你可能會在awk中做到。你需要規範時間格式(你不會說日期的任何事情,所以我假設你只使用時間部分)。

#!/usr/bin/env perl 
use strict; 
use warnings; 
use constant debug => 0; 

my $lo = "09:30"; 
my $hi = "09:40"; 

my $lo_tm = to_minutes($lo); 
my $hi_tm = to_minutes($hi); 

while (<>) 
{ 
    print "Read: $_" if debug; 
    if (m/\D\d\d?:\d\d:\d\d/) 
    { 
     my $tm = normalize_hhmm($_); 
     print "Normalized: $tm\n" if debug; 
     print $_ if ($tm >= $lo_tm && $tm<= $hi_tm); 
    } 
} 

sub to_minutes 
{ 
    my($val) = @_; 
    my($hh, $mm) = split /:/, $val; 
    if ($hh < 0 || $hh > 24 || $mm < 0 || $mm >= 60 || ($hh == 24 && $mm != 0)) 
    { 
     print STDERR "to_minutes(): garbage = $val\n"; 
     return undef; 
    } 
    return $hh * 60 + $mm; 
} 

sub normalize_hhmm 
{ 
    my($line) = @_; 
    my($hhmm, $ampm) = $line =~ m/\D(\d\d?:\d\d):\d\d\s*(AM|PM|am|pm)?/; 
    my $tm = to_minutes($hhmm); 
    if (defined $ampm) 
    { 
     if ($ampm =~ /(am|AM)/) 
     { 
      $tm -= 12 * 60 if ($tm >= 12 * 60); 
     } 
     else 
     { 
      $tm += 12 * 60 if ($tm < 12 * 60); 
     } 
    } 
    return $tm; 
} 

我使用的樣品數據:

<Jan 27, 2013 12:57:16 AM MST> 

Jan 29, 2013 8:58:12 AM 

2013-01-31 06:44:04,883 

Feb 2 00:00:00 AM 
Feb 2 00:59:00 AM 
Feb 2 01:00:00 AM 
Feb 2 01:00:00 PM 
Feb 2 11:00:00 AM 
Feb 2 11:00:00 PM 
Feb 2 11:59:00 AM 
Feb 2 11:59:00 PM 
Feb 2 12:00:00 AM 
Feb 2 12:00:00 PM 
Feb 2 12:59:00 AM 
Feb 2 12:59:00 PM 

Feb 2 00:00:00 
Feb 2 00:59:00 
Feb 2 01:00:00 
Feb 2 11:59:59 
Feb 2 12:00:00 
Feb 2 12:59:59 
Feb 2 13:00:00 
Feb 2 09:31:00 
Feb 2 09:35:23 
Feb 2 09:36:23 
Feb 2 09:37:23 
Feb 2 09:35:00 
Feb 2 09:40:00 
Feb 2 09:40:59 
Feb 2 09:41:00 
Feb 2 23:00:00 
Feb 2 23:59:00 
Feb 2 24:00:00 
Feb 3 09:30:00 
Feb 3 09:40:00 

和它產生了我認爲正確的輸出:

Feb 2 09:31:00 
Feb 2 09:35:23 
Feb 2 09:36:23 
Feb 2 09:37:23 
Feb 2 09:35:00 
Feb 2 09:40:00 
Feb 2 09:40:59 
Feb 3 09:30:00 
Feb 3 09:40:00 

我敢肯定這是不是做的唯一途徑處理;它似乎工作,但。


如果你需要做的最新的分析,那麼你需要使用的日期或時間進行打包處理的一個從CPAN來處理問題。上面的代碼也會在腳本中對時間進行硬編碼。你可能想把它們作爲命令行參數來處理,這是完全可行的,但不是上面的腳本。

+0

我必須考慮perl是否安裝在運行命令的機器上,因爲我將在不同服務器上的不同版本的unix上運行此命令。如果sed不是答案...... AWK解決方案也可以。 – user2014600

+0

然後將Perl轉換爲'awk'。它可能是可行的,甚至可以編寫函數('awk'允許你編寫函數)。但是有些問題需要處理,例如使用函數來執行正則表達式替換,我不願意花時間處理,因爲在我可能感興趣的任何機器上可以使用Perl(這意味着我對Windows不感興趣 - YMMV; Perl可用於Windows,但規定安裝它可能對客戶不可接受)。你需要知道的主要技巧是'\ d' - >'[0-9]'和'\ D' - >'[^ 0-9]'。 –

相關問題