2017-10-05 5 views
0

を使用してJSON要素を追加/交換してください、私は次の入力ファイルを受け取る:JQ:条件付きで更新/入力ファイル

  • input.json:
[ 
{"ID":"aaa_12301248","time_CET":"00:00:00","VALUE":10,"FLAG":"0"}, 
{"ID":"aaa_12301248","time_CET":"00:15:00","VALUE":18,"FLAG":"0"}, 
{"ID":"aaa_12301248","time_CET":"00:30:00","VALUE":160,"FLAG":"0"}, 

{"ID":"bbb_0021122","time_CET":"00:00:00","VALUE":null,"FLAG":"?"}, 
{"ID":"bbb_0021122","time_CET":"00:15:00","VALUE":null,"FLAG":"?"}, 
{"ID":"bbb_0021122","time_CET":"00:30:00","VALUE":22,"FLAG":"0"}, 

{"ID":"ccc_0021122","time_CET":"00:00:00","VALUE":null,"FLAG":"?"}, 
{"ID":"ccc_0021122","time_CET":"00:15:00","VALUE":null,"FLAG":"?"}, 
{"ID":"ccc_0021122","time_CET":"00:30:00","VALUE":20,"FLAG":"0"}, 

{"ID":"ddd_122455","time_CET":"00:00:00","VALUE":null,"FLAG":"?"}, 
{"ID":"ddd_122455","time_CET":"00:15:00","VALUE":null,"FLAG":"?"}, 
{"ID":"ddd_122455","time_CET":"00:30:00","VALUE":null,"FLAG":"?"}, 
] 

することができますようにいくつかの有効な値(FLAG:0)といくつかの無効な値(FLAG: "?")があります。あなたが見ることができるように、オブジェクト1はinput.jsonと同じである

[ 
    {"ID":"aaa_12301248","time_CET":"00:00:00","VALUE":10,"FLAG":"0"}, 
    {"ID":"aaa_12301248","time_CET":"00:15:00","VALUE":null,"FLAG":"?"}, 
    {"ID":"aaa_12301248","time_CET":"00:55:00","VALUE":45,"FLAG":"0"} 
] 

aaa.json: は今、私はこのように見ているファイル(各IDに1つ)を得ましたオブジェクト2は無効です(フラグ: "?")。そのため、オブジェクト2をinput.jsonの正しいオブジェクト(VALUE:18)に置き換える必要があります。 オブジェクトは "time_CET"と "ID"要素で識別できます。

さらに、input.jsonにはaaa.jsonなどの一部ではない新しいオブジェクトが存在します。これらのオブジェクトは配列に追加する必要があり、aaa.jsonの有効なオブジェクトは保持する必要があります。最後に

、aaa.jsonは次のようになります。要約する、だから、

[ 
    {"ID":"aaa_12301248","time_CET":"00:00:00","VALUE":10,"FLAG":"0"}, 
    {"ID":"aaa_12301248","time_CET":"00:15:00","VALUE":18,"FLAG":"0"}, 
    {"ID":"aaa_12301248","time_CET":"00:30:00","VALUE":160,"FLAG":"0"}, 
    {"ID":"aaa_12301248","time_CET":"00:55:00","VALUE":45,"FLAG":"0"} 
] 

:FLAGのため

  1. を見て: "?" in aaa.json
  2. "ID" とマッピング用に "time_CET"を使用して、このオブジェクトをinput.jsonと一致するオブジェクトに置き換えます。
  3. bbb.jsonのために、この繰り返し
  4. 有効なオブジェクトをexisiting維持し、(これは、「ID」フィールドに「AAA」で を開始するオブジェクトのみを意味する)前に がaaa.jsonには存在しなかったinput.jsonからオブジェクトを追加、ccc.json、ddd.json

このようなコマンドを一度に実行することが可能かどうかは、出力が正しいidファイル(aaa、 bbb ccc.json):

jq --argfile aaa aaa.json --argfile bbb bbb.json .... -f prog.jq input.json 

問題は、識別子(aaa、bbb、cccなど)の後の数字が変わる可能性があるということです。だから、必ずオブジェクトが正しいファイル/配列に追加されていることを確認するために、このような文が必要とされるであろう:
if (."ID"|contains("aaa")) then ....

それとも、異なる入力パラメータでプログラムを複数回実行して良いですか?私は確信していません。

ありがとうございます!

答えて

0

はここ

#!/bin/bash 

# usage: update.sh input.json aaa.json bbb.json.... 
# updates each of aaa.json bbb.json.... 

input_json="$1" 
shift 

for i in "[email protected]"; do 
    jq -M --argfile input_json "$input_json" ' 

     # functions to restrict input.json to keys of current xxx.json file 
     def prefix:    input_filename | split(".")[0]; 
     def selectprefix:  select(.ID | startswith(prefix)); 

     # functions to build and probe a lookup table 
     def pk:     [.ID, .time_CET]; 
     def lookup($t;$k):  $t | getpath($k); 
     def lookup($t):   lookup($t;pk); 
     def organize(s):   reduce s as $r ({}; setpath($r|pk; $r)); 

     # functions to identify objects in input.json missing from xxx.json 
     def pks:     paths | select(length==2); 
     def missing($t1;$t2): [$t1|pks] - [$t2|pks] | .[]; 
     def getmissing($t1;$t2): [ missing($t1;$t2) as $p | lookup($t1;$p)]; 

     # main routine 
     organize(.[]) as $xxx 
     | organize($input_json[] | selectprefix) as $inp 
     | map(if .FLAG != "?" then . else . += lookup($inp) end) 
     | . + getmissing($inp;$xxx) 

    ' "$i" | sponge "$i" 

done 

スクリプトが読み込まれ、各aaa.json ...ファイルを更新するために、ループ内でJQを使用して一つのアプローチです。

フィルタは一時オブジェクトを作成して値を参照するのを容易にします[ID,time_CET]aaa.jsonの値をFLAG == "?"で更新します。最終的にに欠けているinput.jsonの値を追加します。

input.jsonの一時ルックアップテーブルは、input_filenameを使用しているため、現在処理中のファイルの名前と一致する接頭辞で始まるキーのみが含まれます。

サンプルを実行します:実行後

$ ./update.sh input.json aaa.json 

aaa.json

[ 
    { 
    "ID": "aaa_12301248", 
    "time_CET": "00:00:00", 
    "VALUE": 10, 
    "FLAG": "0" 
    }, 
    { 
    "ID": "aaa_12301248", 
    "time_CET": "00:15:00", 
    "VALUE": 18, 
    "FLAG": "0" 
    }, 
    { 
    "ID": "aaa_12301248", 
    "time_CET": "00:55:00", 
    "VALUE": 45, 
    "FLAG": "0" 
    }, 
    { 
    "ID": "aaa_12301248", 
    "time_CET": "00:30:00", 
    "VALUE": 160, 
    "FLAG": "0" 
    } 
] 
+0

こんにちは!ご回答有難うございます。それはサンプルとうまく動作します。しかし、複数のオブジェクトが追加されると、新しい配列全体が作成され、aaa.jsonの配列には追加されません。この行をinput.jsonに追加すると、 '{"ID": "aaa_0021122"、 "time_CET": "00:45:00"、 "VALUE":22、 "FLAG": "?"}、 '私は、aaa/bbb/ccc.jsonファイルに1つの配列を追加するだけで、追加されるオブジェクトごとに1つの配列を作成する必要はありません。今までありがとう! – user2556342

+0

私は参照してください。私は 'getmissing'の定義に間違ったところに' ['を持っていました。このバージョンは機能するはずです。学習の練習として、なぜこの特定の場所に配列コンストラクタの先頭を置くのが効果があるのか​​を理解できるかどうかを知りたいかもしれません。 – jq170727