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

答え2

使用幸せ(以前のPerl_6)

fffsed の Raku バージョンが利用可能「トリガー」演算子

次は、開始行でキャプチャを開始し、\s* ExecuteThread空白行でキャプチャを終了します[^^ $$](*.chars == 0また、OK)。必須文字列「String1」と「String2」を文字通りテストします。

~$ raku -ne 'if m/   [^^ \s* ExecuteThread ] / fff / [^^ $$ ] / { .put if \
                m/ | [^^ \s* ExecuteThread ] 
                   | String1 
                   | String2 
                   | [^^ $$ ] / };'  file

問題をクリーンアップするには、必要な文字列を次のクラス変数に抽象化String1できます。String2regexdesired

~$ raku -ne 'my regex desired { String1 | String2 };  \
             if m/   [^^ \s* ExecuteThread ] / fff / [^^ $$ ] / { .put if \
                m/ | [^^ \s* ExecuteThread ] 
                   | <desired>
                   | [^^ $$ ] / };'  file

startまた、同じ抽象化トリックを使用すると、stop宣言変数と正規表現クラス変数を使用してコードをわずかに無条件にすることもできます。だから私たちはこのバージョンに達しました。

~$ raku -ne 'my regex start   { ^^ \s* ExecuteThread };  \
             my regex stop    { ^^ $$ };                 \
             my regex desired { String1  |  String2  };  \
             if (m/ <start> / fff / <stop> /) { 
                .put if m/ <start> | <desired> | <stop> / };'  file

fff初期のグループ化/選択後、より簡単なアプローチがあるかもしれません。削除する出力に不要な行があります(例:最後の節){.put unless m/StackTraceExample/}

入力例:

--blank line --

 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 --

 ExecuteThread: #101 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 --

出力例(上記のすべてのコード例):

 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  

https://docs.raku.org/言語/regexes
https://raku.org

関連情報