2016-10-19 25 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

有三種方法,其中程序可被改進:

  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完全:

reduce keys[] as $key 
    (.; if any(("a","b"); . == $key) then .[$key] |= fromjson else . end) 
+0

Thx for this solution。我只需要添加另一個'null'檢查來使其工作(請參閱編輯問題)。 – Juve

相關問題