ファイルリストからデータを抽出してcsvとして保存するシェルスクリプト

ファイルリストからデータを抽出してcsvとして保存するシェルスクリプト

私はCentOSを使用しています。読みたいファイルのリストがあり、データを抽出してcsvファイルにまとめたいと思います。

ログファイルのテキスト形式は次のとおりです。

...
{"name":"test-api","hostname":"ci47","pid":3202,"level":30,"msg":"File: dsiManager, Method: getContract, End { userId: 'AFC5EH5PIHHLO4XS7SG',\n  clientId: '5003700557',\n  intent: 'YesIntent',\n }","time":"2019-01-21T12:23:10.323Z","v":0}
...

出力形式は次のようにする必要があります。

clientId;intent;time;userId
5003700557;YesIntent;2019-01-21T12:23:10.323Z;AFC5EH5PIHHLO4XS7SG

これを行う最も簡単な方法は何ですか? (あっ、grep...)

ベストアンサー1

JSONでエンコードされたデータを確実に解析するには、JSONコーデックが必要です。これはPerlまたはPython(またはRuby ...)を意味します。私はPerlユーザーなので、Perlソリューションがあります。

まず、一つお話しします。

$ perl -MJSON -ne 'BEGIN { print("clientId;intent;time;userId\n"); } eval { my $obj = from_json($_); my $msg = $obj->{msg}; $msg =~ s/^.*{\s*|\s*,\s*}.*$//g; my %m = map { m/^([^:]*):\s*(.*)/; ($1, $2) } split(/,\s+/, $msg); print("$m{clientId};$m{intent};$obj->{time};$m{userId}\n"); }; warn($@) if ($@);' <x
clientId;intent;time;userId
5003700557;YesIntent;2019-01-21T12:23:10.323Z;AFC5EH5PIHHLO4XS7SG

これはPerlの場合でもやや過剰なので、次は読みやすいスクリプトです。

#!/usr/bin/perl

use strict;
use warnings;
use JSON;

print("clientId;intent;time;userId\n");
while (<>) {
    # Don't choke on malformed lines
    eval {
        my $obj = from_json($_);
        my $msg = $obj->{msg};
        $msg =~
            s/^.*{\s*    # Trim up to and including the leading '{'
            |
            \s*,\s*}.*$  # Trim trailing ',}'
            //gx;
        # Split $msg into key-value pairs
        my %m = map {
            m/^([^:]*)   # Stuff that isn't ':'
            :\s*         # Field separator
            (.*)         # Everything after the separator
            /x;
            ($1, $2)
        } split(/,\s+/, $msg);
        print("$m{clientId};$m{intent};$obj->{time};$m{userId}\n");
    };
    warn($@) if ($@);
}

おすすめ記事