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

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

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

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

grep

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

配列

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

Q&A

解決済

3回答

811閲覧

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

antaka

総合スコア5

シェルスクリプト

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

grep

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

配列

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

0グッド

0クリップ

投稿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にてどうにかできないか考えていますが、
他の方法が浮かばないだけで、特にコマンドにこだわりはありません。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

poto568

2022/11/28 08:05

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

回答3

0

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

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

2022/11/29 09:54

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

0

こういうのは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

総合スコア13671

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

antaka

2022/11/29 09:51

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

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

総合スコア84850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

antaka

2022/11/29 09:46

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

2022/11/29 10:12

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.45%

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

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

質問する

関連した質問