質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

grep

grepはコマンドライン上でテキスト検索を可能にするユーティリティーです。元はUnixのために用意されたものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

解決済

シェルスクリプトにて、ログから特定の結果を抽出したい

antaka
antaka

総合スコア5

シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

grep

grepはコマンドライン上でテキスト検索を可能にするユーティリティーです。元はUnixのために用意されたものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

3回答

0グッド

0クリップ

243閲覧

投稿2022/11/28 07:22

前提

シェルスクリプトにて、ログから条件に一致する結果を抽出したいです。
ログの出力結果は変更できない状態です。

出力されるログの内容

test.log

INFO - 2022-11-01 09:21:55 ~~~~~ WARNING - 2022-11-01 09:21:51 エラーAAA Array ( [aaa] => 101 [bbb] => にんじん [ccc] => 設定が不足しています。 設定値:10 ) WARNING - 2022-11-01 09:21:53 エラーAAA Array ( [aaa] => 101 [bbb] => たまねぎ [ccc] => 設定が不足しています。 設定値:11 ) WARNING - 2022-11-01 09:21:54 エラーAAA Array ( [aaa] => 101 [bbb] => かぼちゃ [ccc] => 設定が不足しています。 設定値:11 ) INFO - 2022-11-01 09:21:55 ~~~~~ INFO - 2022-11-01 09:21:56 ~~~~~ WARNING - 2022-11-01 09:22:54 エラーBBB Array ( [aaa] => 222 [bbb] => かぼちゃ [ccc] => これはエラーBBB )

抽出条件

エラーAAA で aaa の内容とcccの内容のみ抽出しようとしています。
さらにaaa+cccの内容で重複排除しようとしています。

希望する結果

上記ログの場合は、下記のような出力をしたいです。
[aaa] => 101
[ccc] => 設定が不足しています。 設定値:10
[aaa] => 101
[ccc] => 設定が不足しています。 設定値:11

grepの正規表現でINFO部分や他のAAA以外のエラーを排除することはできたのですが、
重複排除の方法が思い浮かばず、進めなくなってしまいました。
grep -A 5 -E ^WARNING.*エラーAAA test.log

grepにてどうにかできないか考えていますが、
他の方法が浮かばないだけで、特にコマンドにこだわりはありません。

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

poto568

2022/11/28 08:05

sedで[aaa]項の末尾改行除去してsortしてuniqとかでできませんかね ([aaa]項のうしろに改行がほしければさらにsedに突っ込むとか…)

回答3

1

こんな感じではどうでしょう。

shell

1cat test.log | 2grep -A 5 -E '^WARNING.*エラーAAA' | 3grep -E '\[\(aaa|ccc\)\]' | 4sed -n '/\[aaa\]/{N;l}'| 5awk '!a[$0]++ {print $0}' | 6sed 's/\\n/\n/;s/\$//'

解説
grepでエラー部分を抽出
grepで[aaa]と[ccc]の行を抽出
sed で1行に結合し改行を\nに変換(行末記号$もついてきてしまう)
awk で重複除去
sed で1行を2行に戻す

投稿2022/11/29 02:51

編集2022/11/29 03:07
kristof

総合スコア4

antaka😄を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

antaka

2022/11/29 09:54

解説もいただきありがとうございます。

1

こういうのはperlがつぶしが効いていいんですよ。

重複排除に連想配列(ハッシュ)を使うのはotnさんのawk版と同じです。
行番号も取り込むことにより、初出順に出力するようにしてみました。

#!/usr/bin/env perl use strict; use warnings; use utf8; binmode STDOUT, ':utf8'; binmode STDERR, ':utf8'; my($n, $e, $aaa, %output); open(my $fhi, '<:utf8', 'test.log') or die; while(<$fhi>){ chomp; (/^WARNING .*エラー(\S+)/ ) and ($n, $e) = ($., $1); (/\[aaa] => (.+)/ ) and $aaa = $1; (/\[ccc] => (.+)/ and $e eq 'AAA') and $output{$aaa.$1} = [$n, $aaa, $1]; } foreach my $x (sort {$output{$a}[0] <=> $output{$b}[0]} keys %output){ # 初出順に出力 printf "[aaa] => %s\n[ccc] => %s\n", $output{$x}[1], $output{$x}[2]; }

投稿2022/11/28 18:09

KojiDoi

総合スコア13422

antaka😄を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

antaka

2022/11/29 09:51

回答いただきありがとうございます。 perl言語には触れたことがありませんでした。 今後スクリプト言語を扱う機会が増えてきたとき、参考にさせていただきます。

0

ベストアンサー

grepだとsort -uと組み合わせるにしてもちょっと無理かと思います。
RubyやPython等の言語を使わないとすると、awkでやるのが簡単でしょう。

sh

1awk ' 2/^WARNING/{ AAA=0 } 3/^WARNING .*エラーAAA/{ AAA=1 } 4/\[aaa\]/ && AAA { aaa = $0 } 5/\[ccc\]/ && AAA { X[aaa "\n" $0] = 1 } 6END{ for(i in X) print i } 7' test.log

出力は順不同です。

投稿2022/11/28 13:37

otn

総合スコア80401

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

antaka

2022/11/29 09:46

回答いただきありがとうございます。 いただいた内容で出力することができました。 awkコマンドの使い方を把握できていませんでしたが、 覚えれば汎用性が高く感じますので、今後勉強しようと思います。 他の方の回答でもできたのですが、一番早かったのでベストアンサーとさせていただきました。
otn

2022/11/29 10:12

awkを知らなくても、他の言語を知っていれば、大体の意味がわかるように書きました。 { }の前の物は、{} 内を実行するif条件、 正規表現だけ書くと「入力行がそれにマッチすれば真」という意味になります。 X はこの場合は、ハッシュとか辞書とかいう文字列添え字の変数ですね。

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

grep

grepはコマンドライン上でテキスト検索を可能にするユーティリティーです。元はUnixのために用意されたものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。