如何在迭代值之前检查jq中是否存在'key'

Rah*_*ess 28 bash json jq

Cannot iterate over null (null)从下面的查询得到,因为.property_historyresult对象中不存在.

.property_history在继续操作之前,如何检查密钥的存在map(...)

我试过用类似的东西 sold_year= `echo "$content" | jq 'if has("property_history") then map(select(.event_name == "Sold"))[0].date' else null end

原始查询:

sold_year=`echo "$content" | jq '.result.property_history | map(select(.event_name == "Sold"))[0].date'`
Run Code Online (Sandbox Code Playgroud)

JSON:

{  
   "result":{  
      "property_history":[  
         {  
            "date":"01/27/2016",
            "price_changed":0,
            "price":899750,
            "event_name":"Listed",
            "sqft":0
         },
         {  
            "date":"12/15/2015",
            "price_changed":0,
            "price":899750,
            "event_name":"Listed",
            "sqft":2357
         },
         {  
            "date":"08/30/2004",
            "price_changed":0,
            "price":739000,
            "event_name":"Sold",
            "sqft":2357
         }
      ]
   }
}
Run Code Online (Sandbox Code Playgroud)

Ini*_*ian 35

您可以使用选择表达jq做你想要达到什么样的东西作为,

jq '.result | select(.property_history != null) | .property_history | map(select(.event_name == "Sold"))[0].date'
"08/30/2004"
Run Code Online (Sandbox Code Playgroud)

  • select(.property_history!= null)是多余的,您可以简单地将其编写为:select(.property_history) (6认同)
  • @icenac - 这两个表达式不等价。谨防! (2认同)

Jus*_*Mai 34

使用has("mykey1")(对于对象)或has(0)(对于数组):

jq 'has("name")' <<< '{"name": "hello"}'
Run Code Online (Sandbox Code Playgroud)

输出:

true
Run Code Online (Sandbox Code Playgroud)

  • `if [ "$( jq 'has("alert")' &lt;&lt;&lt; $this_alert_json )" == "true" ]; 那么` (8认同)
  • 对于 POSIX shell(无重定向功能): `echo "{\"name\": \"hello\"}" | jq '有(“名字”)'` (3认同)

pea*_*eak 11

您可以使用?post-fix运算符:

$ jq '.result | .property_history? | .[] | select(.event_name == "Sold") | .date'
"08/30/2004"
Run Code Online (Sandbox Code Playgroud)

  • 凉。我尝试过...但是它给的是布尔值。看起来把戏是`。[]` (2认同)
  • 您可以将其缩短为`jq '.result.property_history[]?| select(.event_name == "Sold") | .date'` (2认同)
  • 这比公认的答案要紧凑得多。 (2认同)

Cur*_*lop 6

一般模式:

try (...) // "default_value"
Run Code Online (Sandbox Code Playgroud)

按照你的逻辑:

jq 'try (.result.property_history | map(select(.event_name == "Sold"))[0].date) // "default_value"'
Run Code Online (Sandbox Code Playgroud)

try(没有捕获)如果表达式失败则返回空。//如果该值为空,则提供默认值。


ree*_*gnz 5

诀窍是将//empty一起使用:

jq '.result.property_history // empty | map(select(.event_name == "Sold"))[0:1][].date'
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用额外的选择:

jq '.result.property_history // empty | map(select(.event_name == "Sold"))[0:1][].date'
Run Code Online (Sandbox Code Playgroud)


Moh*_*din 5

您可以使用的最短(还有将设置退出代码的好处):

# Example that exits with code 0
jq -e 'has("result")'

# Example that exists with code 0
jq -e '.result[].property_history | has("price")'

# Example that exists with code 1
jq -e '.result[].property_history | has("dummyKey")'
Run Code Online (Sandbox Code Playgroud)

在这些示例中,由于设置了 flag -e,如果has返回 true,则退出代码将被设置为 0,否则为 1。这节省了不必要的额外步骤。