複数の値(たとえば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
-00
Perlには、段落(1つ以上の空行で区切られた)の入力を処理し、複数行の文字列を処理するオプション()があるので、これを達成するためにPerlを使用します。
Perlには、-n
次のように機能するオプションがありますsed -n
(各入力行を自動的に印刷せずに入力を読み取って処理するsed -p
)sed
...
$ 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
表示されません)。したがって、変数はスカラー文字列でなければなりません。declare
env
答え2
使用幸せ(以前のPerl_6)
fff
sed の Raku バージョンが利用可能「トリガー」演算子。
次は、開始行でキャプチャを開始し、\s* ExecuteThread
空白行でキャプチャを終了します[^^ $$]
(*.chars == 0
また、OK)。必須文字列「String1」と「String2」を文字通りテストします。
~$ raku -ne 'if m/ [^^ \s* ExecuteThread ] / fff / [^^ $$ ] / { .put if \
m/ | [^^ \s* ExecuteThread ]
| String1
| String2
| [^^ $$ ] / };' file
問題をクリーンアップするには、必要な文字列を次のクラス変数に抽象化String1
できます。String2
regex
desired
~$ 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