Unixコマンドを使用したファイルの解析

Unixコマンドを使用したファイルの解析

私はUnixに初めてアクセスし、分析する必要があるログファイルがあります。以下は私のサンプルログファイルです。

Container:container_e182_1234
=============================
LogType:container-localizer-syslog
Log Upload Time :Thu Jun 25 12:24:45 +0100 2020
LogLength:0
Log Contents:

LogType:stderr
Log Upload Time :Thu Jun 25 12:24:52 +0100 2020
LogLength:3000
Log Contents:
20/06/25 12:19:33 INFO datasources.FileScanRDD: Reading File path: hdfs://bpaiddev/dev/data/warehouse/clean/falcon/ukc/
20/06/25 12:19:39 ERROR Exception found
java.io.Exception:Not initiated
    at.apache.java.org.Exception(132)
20/06/25 12:19:40 INFO executor.EXECUTOR: Finished task 18.0 in stage 0.0 (TID 18),18994 bytes result sent to driver.
20/06/25 12:20:41 WARN Warning as the node is accessed without started
 
LogType:stdout
Log Upload Time :Thu Jun 25 12:24:52 +0100 2020
LogLength:0
Log Contents:

Container:container_e182_1234
=============================
LogType:container-localizer-syslog
Log Upload Time :Thu Jun 25 12:24:52 +0100 2020
LogLength:0
Log Contents:
    
LogType:stderr
Log Upload Time :Thu Jun 25 12:24:52 +0100 2020
LogLength:3000
Log Contents:

LogType:stdout
Log Upload Time :Thu Jun 25 12:24:52 +0100 2020
LogLength:0
Log Contents:

期待される出力

stderr
Thu Jun 25 12:24:52 +0100 2020
3000
20/06/25 12:19:39 ERROR Exception found
java.io.Exception:Not initiated
    at.apache.java.org.Exception(132)
20/06/25 12:20:41 WARN Warning as the node is accessed without started

出力には、ERROR、WARN、および上記の他の詳細のみを含める必要があります。

ログファイル:

Container:container_e182_1234
=============================
LogType:container-localizer-syslog
Log Upload Time :Thu Jun 25 12:24:45 +0100 2020
LogLength:0
Log Contents:

LogType:stderr
Log Upload Time :Thu Jun 25 12:24:52 +0100 2020
LogLength:3000
Log Contents:
20/06/25 12:19:33 INFO datasources.FileScanRDD: Reading File path: hdfs://bpaiddev/dev/data/warehouse/clean/falcon/ukc/masked_data/parquet/FRAUD_CUSTOMER_INFORMATION/rcd_crt_dttm_yyyymmdd=20200523/part-0042-ed52abc2w.c000.snapp.parquet, range:0-27899, partition values :[20200523]
20/06/25 12:19:39 ERROR Exception found
java.io.Exception:Not initated
    at.apache.java.org........
20/06/25 12:19:40 INFO executor.EXECUTOR: Finished task 18.0 in stage 0.0 (TID 18),18994 bytes result sent to driver.
20/06/25 12:20:41 WARN Warning as the node is accessed without started
 
LogType:stdout
Log Upload Time :Thu Jun 25 12:24:52 +0100 2020
LogLength:0
Log Contents:

Container:container_e182_1234
=============================
LogType:container-localizer-syslog
Log Upload Time :Thu Jun 25 12:24:52 +0100 2020
LogLength:0
Log Contents:
    
LogType:stderr
Log Upload Time :Thu Jun 25 12:24:52 +0100 2020
LogLength:3000
Log Contents:
20/06/25 12:19:33 INFO datasources.FileScanRDD: Reading File path: hdfs://bpaiddev/dev/data/warehouse/clean/falcon/ukc/masked_data/parquet/FRAUD_CUSTOMER_INFORMATION/rcd_crt_dttm_yyyymmdd=20200523/part-0042-ed52abc2w.c000.snapp.parquet, range:0-27899, partition values :[20200523]
20/06/25 12:19:34 INFO executor.EXECUTOR: Finished task 18.0 in stage 0.0 (TID 18),18994 bytes result sent to driver.
     
LogType:stdout
Log Upload Time :Thu Jun 25 12:24:52 +0100 2020
LogLength:0
Log Contents:

どうすればいいですか?この問題を解決するのに役立ちます。ありがとうございます!

答え1

次の1行のコードを使用してsed同じ結果を得ることができます(ファイル名が仮定されますfile)。

sed -n 's/^.*LogType:\(stderr\)$/\1/p; s/^.*Log Upload Time :\(.*\)/\1/p; s/^.*LogLength:\(.*\)$/\1/p; s/^.*\(ERROR\|WARN\).*$/\0/p' file

その後、リダイレクト(>)を使用して出力を別のファイルに保存できます。

読みやすくするために、複数行に分けてください。

sed -n -e 's/^.*LogType:\(stderr\)$/\1/p' \
       -e 's/^.*Log Upload Time :\(.*\)/\1/p' \
       -e 's/^.*LogLength:\(.*\)$/\1/p' \
       -e 's/^.*\(ERROR\|WARN\).*$/\0/p' file

修正する

上記の解決策は、OPによって要求された「LogType:stderr」の一部ではないチャンクを除外しません。これsedには、単独処理に適していない非ローカル情報(同じ行にはありません)が必要です。

次のスクリプトはとawkを使用しますsed(このawkセクションではこの投稿)、次の作業を完了してください。

#!/bin/bash
file=$1
awk '{
  if($0 ~ /LogType/){
    if(hold ~ /LogType:stderr/){
      print hold;
    }
    hold=$0
  }else{
    hold=hold "\n" $0
  }
}END{
  if(hold ~ /LogType:stderr/){
    print hold
  }
}' $file | sed -n -e 's/^.*LogType:\(stderr\)$/\1/p' \
                 -e 's/^.*Log Upload Time :\(.*\)/\1/p' \
                 -e 's/^.*LogLength:\(.*\)$/\1/p'       \
                 -e 's/^.*\(ERROR\|WARN\).*$/\0/p'

答え2

短いスクリプトを使用して行うことができます。ソースログはこのファイルに含まれていますlogdata

#!/bin/bash

tmpfile="/tmp/$0.$$"

sed -n '/stderr/,/^ *$/p' logdata > "$tmpfile"
sed -n 's/^.*LogType:\(.*\)/\1/p
        s/^.*Log Upload Time :\(.*\)/\1/p
        s/^.*LogLength:\(.*\)/\1/p' "$tmpfile"
grep -E "(ERROR|WARN)" "$tmpfile"
rm "$tmpfile"

まずstderrチャンクを一時ファイルに抽出します。次に、2 つのフィールドを削除し、エラーgrepと警告を削除します。最後の2つのステップを接続しようとしましたが、tee成功しませんでした。

一時ファイルがなくてもできます。

sed -n '/stderr/,/^ *$/p' logdata | \
sed -n 's/^.*LogType:\(.*\)/\1/p
        s/^.*Log Upload Time :\(.*\)/\1/p
        s/^.*LogLength:\(.*\)/\1/p
        /ERROR/p
        /WARN/p'

答え3

そしてawk

awk '
  /LogType:stderr/ || (p && /Log( Upload Time|Length)/){
    p=1                    # set flag for stderr block
    sub(/^[^:]+:/, "")     # replace content before `:` including `:`
    print                  # print (modified) line
  }
  p && / (WARN|ERROR) /{ 
    sub(/^[^0-9]*/, "")    # remove unknown prefix
    print
  }  
  /LogType:stdout/{ exit } # exit the script
' file

答え4

GNU sed拡張正規表現パターンを使用して活用してください。

sed -Ee '
  /LogType:stderr/,/^\s*$/!d
  /Log Contents:/,/^\s*$/!{
    s/^[^:]*://;b
  }
  /\s(ERROR|WARN)\s/!d
' logfile

説明する:

  • ファイルを範囲(ログタイプは空白行)に分割し、各範囲を(事前ログコンテンツと後ログコンテンツ)に分割します。

  • サブ範囲 前のブロックから最初のコロン文字まで削除します。しかし、サブスコープのバックブロックにエラーや警告があるかどうかはまだわからないので、まだ印刷しないでください。だから私たちはそれを予約されたスペースに入れました。

  • 下位範囲の後部ブロックに達すると、エラーまたは警告ラインが検出されます。これにより、保留がすぐに検索され、印刷されます。

結果:

stderr
Thu Jun 25 12:24:52 +0100 2020
3000
20/06/25 12:19:39 ERROR Exception found
20/06/25 12:20:41 WARN Warning as the node is accessed without started

エラー/警告メッセージの行番号も必要な場合は上記で修正し、sedコマンドを使用します。

sed -Ee '
  /LogType:stderr/,/^\s*$/!d
  /Log Contents:/,/^\s*$/!{
    s/^[^:]*://;b
  }
  /\s(ERROR|WARN)\s/!d
  p;=;d
' logfile |
sed -Ee '/\s(ERROR|WARN)\s/N;s/\n/ on line #/'

awk n perlなどの他のツールを使用してこれを実行することもできます。注:まず、空白行の末尾のスペースを削除します。

awk '
  BEGIN {
    RS = "\n\n"              
    FS = "\nLog Contents:\n" 
    OFS = "\n"               
    ORS = OFS                
    spc = "[[:blank:]]" 
    str = "(ERROR|WARN)" 
    pat = spc str spc 
  }
  /^LogType:stderr/ &&
  NF == 2 {
    p = $1; gsub(/(^|\n)[^:]+:/, "\n", p);sub(/./, "", p) 
    N = split($2, a, /\n/)
    print p
    for ( i=1; i<=N; i++ ) 
      if ( a[i] ~ pat ) 
        print a[i]
  }
' logfile
perl -F'/^Log\hContents:$/m,$_,2' -00 -ne '
  next if ! /\ALogType:stderr$/m;
  (my $pre = $F[0])=~ s/.*?://gm;
  my $post = join "\n",
    grep { /\s(?:ERROR|WARN)/ }
    split /\n/, $F[1];
  print($pre,$post);
' logfile

関連情報