GNU/Linux >> Linux の 問題 >  >> Linux

日付のない行を含む複数のログ ファイルを日付でマージします (例:スタック トレース)

トリッキー。 date を使用して可能ですが および bash 配列、これは実際のプログラミング言語から恩恵を受ける種類のものです。たとえば Perl の場合:

$ perl -ne '$d=$1 if /(.+?),/; $k{$d}.=$_; END{print $k{$_} for sort keys(%k);}' log*
01:02:03.6497,2224,0022 foo
foo1
2foo
foo3
01:03:03.6497,2224,0022 FOO
FOO1
2FOO
FOO3
01:04:03.6497,2224,0022 bar
1bar
bar2
3bar

以下は、コメント化されたスクリプトに凝縮されていない同じものです:

#!/usr/bin/env perl

## Read each input line, saving it 
## as $_. This while loop is equivalent
## to perl -ne 
while (<>) {
    ## If this line has a comma
    if (/(.+?),/) {
        ## Save everything up to the 1st 
        ## comma as $date
        $date=$1;
    }
    ## Add the current line to the %k hash.
    ## The hash's keys are the dates and the 
    ## contents are the lines.
    $k{$date}.=$_;
}

## Get the sorted list of hash keys
@dates=sort(keys(%k));
## Now that we have them sorted, 
## print each set of lines.
foreach $date (@dates) {
    print "$k{$date}";
}

これは、すべての日付変更線と のみ 日付行にはコンマが含まれています。そうでない場合は、代わりにこれを使用できます:

perl -ne '$d=$1 if /^(\d+:\d+:\d+\.\d+),/; $k{$d}.=$_; END{print $k{$_} for sort keys(%k);}' log*

上記のアプローチでは、ファイルの内容全体をメモリに保持する必要があります。それが問題である場合、問題のない問題は次のとおりです:

$ perl -pe 's/\n/\0/; s/^/\n/ if /^\d+:\d+:\d+\.\d+/' log* | 
    sort -n | perl -lne 's/\0/\n/g; printf'
01:02:03.6497,2224,0022 foo
foo1
2foo
foo3    
01:03:03.6497,2224,0022 FOO
FOO1
2FOO
FOO3    
01:04:03.6497,2224,0022 bar
1bar
bar2
3bar

これは、改行を \0 に置き換えることで、連続するタイムスタンプ間のすべての行を 1 行にまとめただけです。 (これがログ ファイルにある可能性がある場合は、絶対に存在しないことがわかっている任意の文字列を使用してください)。これは sort に渡されました そして tr セリフを取り戻すために。

OPによって非常に正しく指摘されているように、上記のソリューションはすべて再利用する必要があり、ファイルをマージできることを考慮に入れていません。これは 1 つですが、他のものとは異なり、2 つのファイルでしか機能しません:

$ sort -m <(perl -pe 's/\n/\0/; s/^/\n/ if /^\d+:\d+:\d+\.\d+/' log1) \
            <(perl -pe 's/\n/\0/; s/^/\n/ if /^\d+:\d+:\d+\.\d+/' log2) | 
    perl -lne 's/[\0\r]/\n/g; printf'

そして、perl コマンドをエイリアスとして保存すると、以下を取得できます:

$ alias a="perl -pe 's/\n/\0/; s/^/\n/ if /^\d+:\d+:\d+\.\d+/'"
$ sort -m <(a log1) <(a log2) | perl -lne 's/[\0\r]/\n/g; printf'

Linux
  1. Linuxで複数のファイルを圧縮する方法

  2. 特定の日に変更されたすべてのファイルを取得しますか?

  3. /var/log ディレクトリにある 20 個の Linux ログ ファイル

  1. そのファイル名の複数のバリエーションが同じディレクトリに一緒に存在するファイルを検索しますか?

  2. Linuxログファイル

  3. 複数の PDF ファイルを 1 つの PDF に結合/変換する

  1. LinuxのBashで一度に複数のファイルを削除するには?

  2. 大きなファイルの行数を数える

  3. logrotate 構成ファイルの構文 - 複数のワイルドカード エントリが可能ですか?