ファイルからパターンの出現を1つ抽出する

ファイルからパターンの出現を1つ抽出する

以下に示すようなログを含む大きなファイルがあります。エラーの影響を受けたすべてのトランザクション (TR#) を見つけたいと思います。各 TR# ID の出現を 1 つ抽出する必要があります。

どうすればいいでしょうか?

    Apr 30 16:51:29.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704

必要な出力:

    Apr 30 16:51:29.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704

答え1

これは次のように非常に簡単に実行できますawk

$ awk 'c[$5]++==1' file 
Apr 30 16:51:29.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704

または、Perl では次のようになります。

$ perl -ane '$k{$F[4]}++==1 && print' file 
Apr 30 16:51:29.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704

上記では、それぞれの前の数字がTR#IDID の一部であると想定しています。数字は変更可能だが、そのうちの 1 つだけが必要な場合は、代わりに以下を使用します。

$ awk -F'[:.]' 'c[$7]++==1' file 

または

$ perl -F'[:.]' -ane '$k{$F[6]}++==1 && print' file 

答え2

各メッセージの最初の出現を取得して印刷するには、次のようにします。

awk '! m[$5] {m[$5]=$0} END{for (e in m) print m[e]}'

テストするために、例のタイムスタンプを連続的にしました (また、最終的な切り捨てられたエラー値も修正しました)。

$ awk '! m[$5] {m[$5]=$0} END{for (e in m) print m[e]}' tr2.log
Apr 30 16:51:27.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
Apr 30 16:51:31.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704

@terdonに感謝

答え3

必要なことを実行する Perl スクリプトは次のとおりです。

#!/usr/bin/perl

#Read each line
while ($line = <>) {
  # Extract the transaction ID by looking for the text TR followed by digits
  ($trid) = $line =~ /.*(TR#\d+).*/ ;
  # If we've not seen the ID before, print it out
  unless ($trids{$trid}) {
    print $line;
  }
  # Remember the ID so we don't print it out again
  $trids{$trid} = 1;
}

あなたの入力を使用して呼び出すと、次のようになります:

temeraire:ul jenny$ ./extract.pl in.txt 
    Apr 30 16:51:29.574 application.crit: [6104]:TR#14. Transaction send can not be sent. Error Code: 704
    Apr 30 16:51:29.574 application.crit: [6104]:TR#238. Transaction send can not be sent. Error Code: 704

答え4

GNUを通じてsed、盗まれたこれ答えは、

sed '$!N; /^\(.*\)\n\1$/!P; D' file

関連情報