SED 範囲一致は、前の日付パターンと一致し、一致する範囲を出力に含めます。

SED 範囲一致は、前の日付パターンと一致し、一致する範囲を出力に含めます。

複数の値(たとえばstr_pattern)に変数を設定し、sedコマンドの値を使用して範囲を前の空行または後方に一致させるのに問題がありますExecuteThread

  • サンプルスクリプトの断片
    str_pattern="String1
    String2"
    
    tac $file | sed -n '/'"$str_pattern"'/,/^$/p' | tac
    
  • 入力ファイルの例
2023-01-01 01:00:00
    --blank line --
     ExecuteThread: #100 Exception in thread "main" java.lang.RuntimeException: 
     at com.stackify.stacktrace.StackTraceExample.methodB(StackTraceExample.java:13)  
     at com.stackify.stacktrace.something
     
     ExecuteThread: #101 Exception in thread "main" java.lang.RuntimeException: 
     at com.stackify.stacktrace.StackTraceExample.methodB(StackTraceExample.java:13)  
     at com.stackify.stacktrace.String1.line1   
     at com.stackify.stacktrace.String1.line2  
     at com.stackify.stacktrace.StackTraceExample.methodA(StackTraceExample.java:9)
      
     --blank line --
2023-01-01 02:00:00
    ExecuteThread: #100 Exception in thread "main" java.lang.RuntimeException: 
     at com.stackify.stacktrace.StackTraceExample.methodB(StackTraceExample.java:13)  
     at com.stackify.stacktrace.something

     ExecuteThread: #102 Exception in thread "main" java.lang.RuntimeException: 
     at com.stackify.stacktrace.StackTraceExample.methodB(StackTraceExample.java:13)  
     at com.stackify.stacktrace.String2.line1   
     at com.stackify.stacktrace.String2.line2  
     at com.stackify.stacktrace.StackTraceExample.methodA(StackTraceExample.java:9)
      
     --blank line --
  • 希望の出力
2023-01-01 01:00:00
    ExecuteThread: #101 Exception in thread "main" java.lang.RuntimeException: 
         at com.stackify.stacktrace.String1.line1   
         at com.stackify.stacktrace.String1.line2  
2023-01-01 02:00:00    
    ExecuteThread: #102 Exception in thread "main" java.lang.RuntimeException: 
         at com.stackify.stacktrace.String2.line1   
         at com.stackify.stacktrace.String2.line2 

ベストアンサー1

-00Perlには、段落(1つ以上の空行で区切られた)の入力を処理し、複数行の文字列を処理するオプション()があるので、これを達成するためにPerlを使用します。

Perlには、-n次のように機能するオプションがありますsed -n(各入力行を自動的に印刷せずに入力を読み取って処理するsed -psed...

$ perl -00 -n -e '
    if (/String1|String2/) {
      s/^.*StackTraceExample.*$//mg;
      s/\n\n/\n/g;
      print;
    }' input.txt 
 ExecuteThread: #101 Exception in thread "main" java.lang.RuntimeException:
 at com.stackify.stacktrace.String1.line1
 at com.stackify.stacktrace.String1.line2

 ExecuteThread: #101 Exception in thread "main" java.lang.RuntimeException:
 at com.stackify.stacktrace.String2.line1
 at com.stackify.stacktrace.String2.line2

英語で:

現在の段落にString1またはString 2が含まれている場合は、StackTraceExample(存在する場合)を含むすべての行を削除し、StackTraceExample行を削除した後に残っている可能性がある追加の改行を削除してから、修正された段落を印刷します。

shまたはbashスクリプトからPerlにString1、String2、... StringNを渡す必要がある場合、1つの方法は環境からエクスポートされた変数を渡すことです。

#!/bin/sh

str_pattern="String1|String2"
excl_pattern="StackTraceExample"
export str_pattern excl_pattern

perl -00 -n -e '
  if (/$ENV{str_pattern}/) {
    s/^.*(?:$ENV{excl_pattern}).*$//mg;
    s/\n\n/\n/g;
    print
  }' input.txt 
 ExecuteThread: #101 Exception in thread "main" java.lang.RuntimeException:
 at com.stackify.stacktrace.String1.line1
 at com.stackify.stacktrace.String1.line2

 ExecuteThread: #101 Exception in thread "main" java.lang.RuntimeException:
 at com.stackify.stacktrace.String2.line1
 at com.stackify.stacktrace.String2.line2

str_patternとの値はexcl_pattern固定文字列ではなくPerl正規表現として解釈されるので、リテラルで処理したい特殊文字をエスケープします。

%ENV環境変数へのアクセスを提供するPerlのハッシュ(関連配列)。

注:残念ながらbash配列は効果的にエクスポートできません(exportエラーコードは返されませんが、外部プログラム環境では使用できません。たとえば、export foo=(1 2 3); declare -p foo ; env | grep ^foo=bashで実行すると出力には表示されますが、出力にはfoo表示されません)。したがって、変数はスカラー文字列でなければなりません。declareenv

おすすめ記事