2016-10-19 20 views
1

JSONで引用されたJSONを解析する必要がある場合があります。 私は知っていますオプションのの属性には引用符付きのJSONが含まれています。 したがって、属性キーが使用可能なキーのリストに含まれているかどうかを確認したいと思います。jq:キーが定義済みのキーのリストにあるかどうかのテスト

# attributes "a" and "b" contain quoted JSON 
echo '{"a":"{\"x\":1}","y":2}' | 
jq -c ' 
    def is_json($o): ["a","b"] | (map(select(. == $o)) | length) > 0; 
    with_entries(if is_json(.key) then .value = (.value|fromjson) else . end) 
' 

は、これはすでに所望の出力を生成します:{"a":{"x":1},"y":2}私はすでに次のよう持っています。しかし、属性名のチェックはjqは、組み込み関数をたくさん提供していることを考えると、不器用に見えるなどhasincontainsinside、など

質問:がかどうかをチェックするのより良い方法があります属性キーが指定されたリストにありますか?

編集:ピークの答えに基づいて、現在の解決策があります。

#!/bin/bash 
to_array_string() { echo "$*" | awk -v OFS='","' 'NF > 0 {$1=$1; print "\""$0"\""}'; } 
to_json_array_string() { echo "["`to_array_string "[email protected]"`"]"; } 

parse_json_jq() { jq -c " 
    reduce keys[] as \$key 
    (.; if any((`to_array_string "[email protected]"`); . == \$key) and .[\$key] != null then .[\$key] |= fromjson else . end) 
";} 

答えて

2
あなたのプログラムを向上させることが可能な3つの方法があります

  1. (効率)(is_jsonに)不必要な配列の作成を避けること。
  2. (効率) "短絡"セマンティクスを使用して回避すること 不必要に反復する。
  3. (効率)with_entriesに関連する構築/分解を回避します。

ここで提供されている選択肢が、よりシンプルに、より簡潔に、またはより読みやすくなることに大変賛成すると思います。

後でJQかのバージョン1.5を使用している場合は、任意の/ 2を使用していたことができ 主な改良点:また

def is_json($o): any(("a","b"); . == $o); 

with_entries(if is_json(.key) then .value |= fromjson else . end) 

お知らせの使用「| =」あなたは「=」を使用していました。

あなたJQはany/2を持っていない場合、あなたはそれが短絡セマンティクスを欠いても、次のよう 定義を使用することができます。

最後に
def any(s): reduce s as $i (false; . == true or $i); 

with_entriesを使用しないように、あなたがreduceを使用して排除することができるis_json完全に:

+0

このソリューションのThx。私はそれを動作させるために別の 'null'チェックを追加する必要がありました(質問への編集参照)。 – Juve

関連する問題