
ログファイルをフィルタリングし、2つの一致の間に数行を印刷し、最後の一致のみを印刷したいと思います。
サンプルファイルの内容:
2023-03-08 11:12:44,306 - Code Deploy - INFO - Received signal
2023-03-08 11:12:44,306 - Code Deploy - INFO - Received message signal
2023-03-08 11:12:44,306 - Code Deploy - INFO - Branch is Testing
2023-03-08 11:12:44,307 - Code Deploy - INFO - Deployment started
2023-03-08 11:13:31,782 - Code Deploy - INFO - Old version2_0_5_12
2023-03-08 11:13:31,783 - Code Deploy - INFO - New version2_0_5_13
2023-03-08 11:13:32,553 - Code Deploy - INFO - Permission fixed
2023-03-08 11:13:32,554 - Code Deploy - INFO - Deployment finished
2023-03-08 11:13:34,900 - Code Deploy - ERROR - !!!!!!!!!! EXCEPTION !!!!!!!!!(535, b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials z16-20020a170903019000b0019a97a4324dsm9818181plg.5 - gsmtp')Traceback (most recent call last):
File "/root/code-dployment/server/deploy.py", line 94, in send_email
server.login(gmail_user, gmail_password)
File "/usr/lib/python3.5/smtplib.py", line 729, in login
raise last_exception
File "/usr/lib/python3.5/smtplib.py", line 720, in login
initial_response_ok=initial_response_ok)
File "/usr/lib/python3.5/smtplib.py", line 641, in auth
raise SMTPAuthenticationError(code, resp)
smtplib.SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials z16-20020a170903019000b0019a97a4324dsm9818181plg.5 - gsmtp')
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received message signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Branch is Testing
2023-03-09 11:52:57,195 - Code Deploy - INFO - Deployment started
2023-03-09 11:53:58,246 - Code Deploy - INFO - Old version2_0_5_13
2023-03-09 11:53:58,246 - Code Deploy - INFO - New version2_0_5_14
2023-03-09 11:53:58,498 - Code Deploy - INFO - Permission fixed
2023-03-09 11:53:58,498 - Code Deploy - INFO - Deployment finished
2023-03-09 11:54:00,797 - Code Deploy - ERROR - !!!!!!!!!! EXCEPTION !!!!!!!!!(535, b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials k17-20020aa790d1000000b005907716bf8bsm11097506pfk.60 - gsmtp')Traceback (most recent call last):
File "/root/code-dployment/server/deploy.py", line 94, in send_email
server.login(gmail_user, gmail_password)
File "/usr/lib/python3.5/smtplib.py", line 729, in login
raise last_exception
File "/usr/lib/python3.5/smtplib.py", line 720, in login
initial_response_ok=initial_response_ok)
File "/usr/lib/python3.5/smtplib.py", line 641, in auth
raise SMTPAuthenticationError(code, resp)
smtplib.SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials k17-20020aa790d1000000b005907716bf8bsm11097506pfk.60 - gsmtp')
2つのスキーマ間のコンテンツをインポートする必要があります。
Pattern1 = '信号受信'
Pattern2 = '配布完了'
予想される結果:
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received message signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Branch is Testing
2023-03-09 11:52:57,195 - Code Deploy - INFO - Deployment started
2023-03-09 11:53:58,246 - Code Deploy - INFO - Old version2_0_5_13
2023-03-09 11:53:58,246 - Code Deploy - INFO - New version2_0_5_14
2023-03-09 11:53:58,498 - Code Deploy - INFO - Permission fixed
2023-03-09 11:53:58,498 - Code Deploy - INFO - Deployment finished
bashスクリプトでAWKコマンドを使用したいと思います。次のコマンドを使用して、2つのモード間でコンテンツをフィルタリングするソリューションを見つけました。
# awk '/Received signal/,/Deployment finished/' /tmp/result.log
完全一致する行のすべての項目を印刷しますが、一致するパターンの最後の項目のみを印刷するようにフィルタリングする必要があります。
上記のコマンドの出力は次のようになります。
2023-03-08 11:12:44,306 - Code Deploy - INFO - Received signal
2023-03-08 11:12:44,306 - Code Deploy - INFO - Received message signal
2023-03-08 11:12:44,306 - Code Deploy - INFO - Branch is Testing
2023-03-08 11:12:44,307 - Code Deploy - INFO - Deployment started
2023-03-08 11:13:31,782 - Code Deploy - INFO - Old version2_0_5_12
2023-03-08 11:13:31,783 - Code Deploy - INFO - New version2_0_5_13
2023-03-08 11:13:32,553 - Code Deploy - INFO - Permission fixed
2023-03-08 11:13:32,554 - Code Deploy - INFO - Deployment finished
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received message signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Branch is Testing
2023-03-09 11:52:57,195 - Code Deploy - INFO - Deployment started
2023-03-09 11:53:58,246 - Code Deploy - INFO - Old version2_0_5_13
2023-03-09 11:53:58,246 - Code Deploy - INFO - New version2_0_5_14
2023-03-09 11:53:58,498 - Code Deploy - INFO - Permission fixed
2023-03-09 11:53:58,498 - Code Deploy - INFO - Deployment finished
答え1
awkを使用し、次のいずれかのスクリプトによく似ています。@terdonの返信しかし、私の考えでは、awkのcondition { action }
基本構造を使用する方がより慣用的です。
$ awk '
/Received signal/ { f=1; rec="" }
f { rec = rec $0 ORS }
/Deployment finished/ { f=0 }
END { if (f=="0") printf "%s", rec }
' file
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received message signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Branch is Testing
2023-03-09 11:52:57,195 - Code Deploy - INFO - Deployment started
2023-03-09 11:53:58,246 - Code Deploy - INFO - Old version2_0_5_13
2023-03-09 11:53:58,246 - Code Deploy - INFO - New version2_0_5_14
2023-03-09 11:53:58,498 - Code Deploy - INFO - Permission fixed
2023-03-09 11:53:58,498 - Code Deploy - INFO - Deployment finished
これと@terdonの答えの間のいくつかの機能的な違いは次のとおりです。
RS='\r\n'
ORSをRSとは異なる値に設定することを決定した場合(たとえば、に変換したい場合ORS='\n'
)、必要なレコード終端が作成され、@terdonはORSを使用してほとんどの出力の終わりにRS値を再現します。- 入力ファイルに行がない場合、@terdonは空の行を印刷し、
Received signal
ファイルは出力を生成しません。 - 入力に2つの区切り文字がある場合、このコマンドは区切り文字間のテキストのみを印刷しますが、@terdonは後続の行がなくても行の後のすべての項目を
Received signal
印刷しますDeployment finished
。
あなたの質問に関連してawk '/Received signal/,/Deployment finished/' /tmp/result.log
- 範囲式を使用しないでフラグを使用してください。awkでは、開始終了範囲表現が常に便利です。範囲式を使用するこれまでに公開されているすべての回答に示すように、同じ条件に対して2つのテストが必要です。
答え2
ファイルを反転して範囲内にないすべての行を削除し、行/Deployment finished/,/Received signal/
範囲の終わりが一致したらすぐに終了します。その後、結果を反転します。
tail -r file |
sed -e '/Deployment finished/,/Received signal/!d' -e '/Received signal/q' |
tail -r
GNUシステムユーザーは上記の方法のtac
代わりにこれを使用できます。tail -r
使用する必要があると思われる場合は、上記のawk
パイプsed
ラインのコマンドを次のように変更してください。
awk '/Deployment finished/,/Received signal/; /Received signal/ { exit }'
問題のデータを提供する出力:
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received message signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Branch is Testing
2023-03-09 11:52:57,195 - Code Deploy - INFO - Deployment started
2023-03-09 11:53:58,246 - Code Deploy - INFO - Old version2_0_5_13
2023-03-09 11:53:58,246 - Code Deploy - INFO - New version2_0_5_14
2023-03-09 11:53:58,498 - Code Deploy - INFO - Permission fixed
2023-03-09 11:53:58,498 - Code Deploy - INFO - Deployment finished
答え3
簡単な方法は、各一致を変数に保存し、前の内容を上書きし、スクリプトの最後に変数を印刷することです。
$ awk '{
if(/Received signal/){k=1; v=$0}
else if(k==1){
v=v RS $0;
if(/Deployment finished/){ k=0 }
}
}
END{ print v }' result.log
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received message signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Branch is Testing
2023-03-09 11:52:57,195 - Code Deploy - INFO - Deployment started
2023-03-09 11:53:58,246 - Code Deploy - INFO - Old version2_0_5_13
2023-03-09 11:53:58,246 - Code Deploy - INFO - New version2_0_5_14
2023-03-09 11:53:58,498 - Code Deploy - INFO - Permission fixed
2023-03-09 11:53:58,498 - Code Deploy - INFO - Deployment finished
または、tac
ファイルを反転してから最初の一致を印刷することもできます。
$ tac result.log |
awk '/Deployment finished/,/Received signal/{
print;
if(/Received signal/){ exit }
}' | tac
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received message signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Branch is Testing
2023-03-09 11:52:57,195 - Code Deploy - INFO - Deployment started
2023-03-09 11:53:58,246 - Code Deploy - INFO - Old version2_0_5_13
2023-03-09 11:53:58,246 - Code Deploy - INFO - New version2_0_5_14
2023-03-09 11:53:58,498 - Code Deploy - INFO - Permission fixed
2023-03-09 11:53:58,498 - Code Deploy - INFO - Deployment finished
答え4
使用幸せ(以前のPerl_6)
~$ raku -e 'my $k; my @v; for lines() {
if /Received \s signal/ {$k = 1; @v = $_}
elsif ($k == 1) { @v.push: $_ };
if /Deployment \s finished/ {$k = 0}
}; .put for @v;' file
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received message signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Branch is Testing
2023-03-09 11:52:57,195 - Code Deploy - INFO - Deployment started
2023-03-09 11:53:58,246 - Code Deploy - INFO - Old version2_0_5_13
2023-03-09 11:53:58,246 - Code Deploy - INFO - New version2_0_5_14
2023-03-09 11:53:58,498 - Code Deploy - INFO - Permission fixed
2023-03-09 11:53:58,498 - Code Deploy - INFO - Deployment finished
上記のコードは@terdonの偉大なawk
コードに恥ずかしいものですが、Rakuで書き直されました。 @terdonが指摘した鍵は、公開正規表現が見つかる@v
たびに「保存変数」(この場合は配列)を上書きすることです。/Received \s signal/
ここではlines
すべてトピック変数に1つずつロードされるため、$_
コードを使用します。@v = $_
/Deployment \s finished/
ファイルの終わりに達したときに終わりが表示されるまで何も返さないようにするには(たとえば、「フル履歴」要件)、最終出力ステートメントを次のようにput
変更します。
.put if $k == 0 for @v;
#OR
.put unless $k == 1 for @v;
https://docs.raku.org/言語/control.html#Control_flow
https://raku.org