2017-10-08 13 views
0

私は2つの.jsonファイルを持って、最初のものはデータが含まれています。JQ - STARTSWITHを使用してマップオブジェクト値()

data.json

[ 
{"ID_EXT_LARGE":"aaa_1234411","xy":"xyz"}, 
{"ID_EXT_LARGE":"bbb_1474411","xy":"cfg"}, 
{"ID_EXT_LARGE":"ccc_8944411","xy":"drt"}, 
{"ID_EXT_LARGE":"aaa_1234411","xy":"kai"} 
] 

他方はIDが含まれています:

id_array.json

[ 
{"ID_EXT":"aaa","ID_WEB":30,"ID_ACC":"one"}, 
{"ID_EXT":"bbb","ID_WEB":40,"ID_ACC":"two"}, 
{"ID_EXT":"ccc","ID_WEB":50,"ID_ACC":"three"} 
] 

これで、ID_EXT_LARGEとID_EXTのマッピングを使用して、data.jsonのオブジェクトに "ID_WEB"と "ID_ACC"プロパティを取得しようとしました。

問題は、ID_EXTにはID_EXT_LARGEの最初の文字しか含まれていないという点です。 - 期待される結果は、(拡張data.jsonファイルである必要があります):

data.json

[ 
{"ID_EXT_LARGE":"aaa_1234411","ID_WEB":30,"ID_ACC":"one","xy":"xyz"}, 
{"ID_EXT_LARGE":"bbb_1474411","ID_WEB":40,"ID_ACC":"two","xy":"cfg"}, 
{"ID_EXT_LARGE":"ccc_8944411","ID_WEB":50,"ID_ACC":"three","xy":"drt"}, 
{"ID_EXT_LARGE":"aaa_1234411","ID_WEB":30,"ID_ACC":"one","xy":"kai"} 
] 

私はID_WEBのためにそれを試してみましたが、このような何かを考えていたが、(forループ)だけのアイデアだった:

script.jq

def getIDWEB(id_array); 
     for i .... 
      if ."ID_EXT_LARGE"|startswith(id_array[i].ID_EXT) then id_array[i].ID_WEB end 
     end 
    ; 

    def setIDWEB(id_array): 
    .ID_WEB = getIDWEB(id_array) 
    ; 

    ($id_array) as $id_array 
    | map(setIDWEB($id_array)) 

おそらく私は複雑すぎると思っています。これは実際には1ライナーですか?

答えて

1

id_array.jsonから「テーブル」オブジェクトを作成する手法です。この関数は、テーブルを作成します。$id_arrayでサンプルid_array.json

def maketable: 
    reduce $id_array[] as $i (
    {} 
    ; .[$i.ID_EXT] = ($i | {ID_WEB,ID_ACC}) 
) 
; 

これは

{ 
    "aaa": { 
    "ID_WEB": 30, 
    "ID_ACC": "one" 
    }, 
    "bbb": { 
    "ID_WEB": 40, 
    "ID_ACC": "two" 
    }, 
    "ccc": { 
    "ID_WEB": 50, 
    "ID_ACC": "three" 
    } 
} 

のようなオブジェクトを返します。この関数は、data.jsonからオブジェクトを取り出し、テーブルに対応する検索キーを返します。

def getkey: .ID_EXT_LARGE | split("_")[0] ; 

たとえば

{"ID_EXT_LARGE":"aaa_1234411","xy":"xyz"} 

与えられ、それが結果出力がで生成することができ、これらの二つの機能で

"aaa" 

を返します。

maketable as $idtable 
| map(. + $idtable[ getkey ]) 

ここで一緒にすべてを入れて更新するspongeを使用するスクリプトがあるdata.json

#!/bin/bash 
jq -M --argfile id_array id_array.json ' 

    def maketable: 
     reduce $id_array[] as $i (
     {} 
     ; .[$i.ID_EXT] = ($i | {ID_WEB,ID_ACC}) 
    ) 
    ; 
    def getkey: .ID_EXT_LARGE | split("_")[0] ; 

     maketable as $idtable 
    | map(. + $idtable[ getkey ]) 

' data.json | sponge data.json 
ここ

サンプルの実行後にdata.jsonです:より一般的なINDEX組み込み(以下の定義)がある場合maketableアウトpeakなどの点が

def maketable: INDEX($id_array[]; .ID_EXT) | map_values(del(.ID_EXT)) ; 

で置き換えることができることを

[ 
    { 
    "ID_EXT_LARGE": "aaa_1234411", 
    "xy": "xyz", 
    "ID_WEB": 30, 
    "ID_ACC": "one" 
    }, 
    { 
    "ID_EXT_LARGE": "bbb_1474411", 
    "xy": "cfg", 
    "ID_WEB": 40, 
    "ID_ACC": "two" 
    }, 
    { 
    "ID_EXT_LARGE": "ccc_8944411", 
    "xy": "drt", 
    "ID_WEB": 50, 
    "ID_ACC": "three" 
    }, 
    { 
    "ID_EXT_LARGE": "aaa_1234411", 
    "xy": "kai", 
    "ID_WEB": 30, 
    "ID_ACC": "one" 
    } 
] 

注意利用可能です。

def INDEX(stream; idx_expr): 
    reduce stream as $row (
    {} 
    ; .[$row|idx_expr| if type != "string" then tojson else . end] |= $row 
) 
; 
+0

jqに 'INDEX/1'がある場合は、' maketable'の代わりに次のように書くことができます:INDEX(.ID_EXT)| map_values(del(.ID_EXT)) – peak

関連する問題