2017-01-20 76 views
2

這裏匹配的數據是從我的捲曲的樣品JSON響應:數值參數--arg不與==

{ 
    "success": true, 
    "message": "jobStatus", 
    "jobStatus": [ 
    { 
     "ID": 9, 
     "status": "Successful" 
    }, 
    { 
     "ID": 2, 
     "status": "Successful" 
    }, 
    { 
     "ID": 99, 
     "status": "Failed" 
    } 
    ] 
} 

我想檢查ID = 2的狀態。這裏是我試過的命令:

cat test.txt|jq --arg v "2" '.jobStatus[]|select(.ID == $v)|.status' 

響應:有沒有

我試着不帶引號值2,仍然沒有結果。

相反,如果我試圖用文字2的命令,它的工作原理:

cat test.txt | jq '.jobStatus[]|select(.ID == 2)|.status' 

響應:

"Successful" 

我卡住了。任何人都可以幫我找出問題嗎?

回答

5

jq是數據類型感知

  • .ID,如在JSON輸入所定義,是

  • 但任何命令行參數通過--arg(如v這裏)總是一個字符串(你是否引用價值),

所以,爲了對它們進行比較,你必須使用顯式類型轉換,如用tonumber/1

jq --arg v '2' '.jobStatus[] | select(.ID == ($v | tonumber)) | .status' test.txt 

鑑於此處僅通過了標量的說法,因此使用以下解決方案時使用了--argjsonjq v1。5+)是有點矯枉過正的,但它是一個替代明確的類型轉換在於傳遞JSON參數有效傳遞類型數據

jq --argjson v '{ "ID": 2 }' '.jobStatus[] | select(.ID == $v.ID) | .status' test.txt 

peak's answer證明即使--argjson v 2作品(在這種情況下直接比較$v作品),這當然是concis Ë的解決方案,但可能需要一個解釋:即使

  • 2可能不看起來像JSON,它是:它是包含了類型數單一個有效的JSON文本(參見json.org)。

    • 具體而言,它是一個事實,即2無引號令牌與數字,使得它在JSON(JSON的串的上下文中,數 - 值當量"2"開始,其中來自外殼將不得不以'"2"'傳遞 - 請注意嵌入的雙引號)。
  • 因此jq解釋--argjson -v 2作爲,和比較.ID == $v作品如預期(請注意,這同樣適用於--argjson -v '2'/--argjson -v "2",其中殼移除引號jq看到值之前)。
    相比之下,您通過--arg的任何內容始終是字符串原樣使用的值。

  • 換句話說:--argjson,其目的是接受任意的JSON文本作爲字符串(如在上面的例子'{ "ID": 2 }'),也可以用於傳遞數串標量迫使它們作爲數字解釋。
    相同的技術也適用於布爾字符串truefalse

的帽子 peak他的幫助的

提示。

3

假設您想要檢查JSON值2,您可以選擇將--arg的參數轉換爲數字,或者使用帶數字參數的--argjson。這些替代方案如下所示:

jq --arg v 2 '.jobStatus[] | select(.ID == ($v|tonumber) | .status' 

jq --argjson v 2 '.jobStatus[] | select(.ID == $v) | .status' 

請注意,--argjson需要相對較新版本的jq。

當然,如果你想「正常化」 .ID以便它作爲一個字符串總是處理,你可以寫:

jq --arg v 2 '.jobStatus[] | select((.ID|tostring) == $v) | .status'