ある行から別の行へ Grep

ある行から別の行へ Grep

何千行ものファイルがあります。ある行から別の行に移動して、これらの行の間にあるすべての項目を含める必要があります。

Wed Nov 25 23:08:01 GMT 2015つまり、からの行はWed Nov 25 23:59:24 GMT 2015

[...]
abc
abc
abc
Wed Nov 25 23:08:01 GMT 2015
def
def
def
def
... (1000 lines with def)
Wed Nov 25 23:59:24 GMT 2015
xyz
xyz
xyz
[...]

正しいgrep表現が何であるかを提案できますか?

答え1

sedとgrepの組み合わせがトリックを実行する必要があります。このような:

sed '1,/Wed Nov 25 23:08:01 GMT 2015/d;/Wed Nov 25 23:59:24 GMT 2015/,$d' < file.txt | grep <yourstring>

この例には、日付と一致する行は含まれず、日付間のすべての行のみが含まれます。

答え2

それが目的でgrepはないので、どのように表現するかを提示することはできません。grep

perl代わりにandスコープ演算子を使用することをお勧めします。

#!/usr/bin/env perl
use strict;
use warnings;

while ( <> ) {  
    print if m/Wed Nov 25 23:08:01 GMT 2015/ .. /Wed Nov 25 23:59:24 GMT 2015/;
}

単一行にフォーマットすると、次のようになります。

perl -ne 'print if m/Wed Nov 25 23:08:01 GMT 2015/ .. /Wed Nov 25 23:59:24 GMT 2015/'

注 – 正規表現などの数値一致ではなく、テキストベースの一致を実行します。この日付は、時間に基づいて変換して使用できます。

次のように数値計算ができます。

#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece;

my $start = Time::Piece->strptime( 'Nov 25 23:00:00 GMT 2015',
    '%b %d %H:%M:%S GMT %Y' );
my $end = Time::Piece->strptime( 'Nov 25 23:59:00 GMT 2015',
    '%b %d %H:%M:%S GMT %Y' );

my $last_timestamp;
while ( my $line = <DATA> ) {
    chomp($line);
    my $timestamp =
        eval { Time::Piece->strptime( $line, '%a %b %d %H:%M:%S GMT %Y' ) };
    $timestamp //= $last_timestamp;
    if ( $timestamp > $start and $timestamp < $end ) { 
        print $line,"\n";
    }
    $last_timestamp = $timestamp;
}

__DATA__
[...]
abc
abc
abc
Wed Nov 25 23:08:01 GMT 2015
def
def
def
def
... (1000 lines with def)
Wed Nov 25 23:59:24 GMT 2015
xyz
xyz
xyz
[...]

(注 - 日付は入力した文字列と一致しません。数値で解析し、範囲内で確認してください。)

関連情報