Command-Line

在 jq 中使用多個萬用字元來選擇 JSON 文件中的對象

  • January 9, 2018

我有一個 JSON 文件,其中包含以下結構中的數千條記錄,具有不同的值。

例子:

{"in": 5,"li": [{"st": 1508584161,"abc": 128416626,"ta": 33888}],"usr": {"is": "222108923573880","ie": "222108923573880"},"st2": 1508584161,"ei": {"ev": 0,"rt": 10},"rn": 947794,"st1": 1508584161}
{"in": 5,"li": [{"st": 1508584174,"abc": 128572802,"ta": 33504}],"usr": {"is": "222108923573880","ie": "222108923573880"},"st2": 1508584174,"ei": {"ev": 0,"rt": 19},"rn": 947795,"st1": 0}
{"in": 5,"li": [{"st": 1508584145,"abc": 279682,"ta": 50000}],"usr": {"is": "222108923573880","ie": "222108923573880"},"st2": 1508584145,"ei": {"ev": 0,"rt": 18},"rn": 947796,"st1": 1508584145}
{"in": 5,"li": [{"st": 1508584183,"abc": 1378680,"ta": 49840}],"usr": {"is": "222108923573880","ie": "222108923573880"},"st2": 1508584183,"ei": {"ev": 0,"rt": 10},"rn": 947797,"st1": 1508584186}
{"nt": 4}

我正在嘗試在 JSON 文件中選擇符合以下條件的對象(記錄)並輸出到另一個文件。

st1 < 或 = st2

st1 不為 0

st2 不為 0

st1 小於 2147483647

st2 小於 2147483647

在輸出中,原始文件的頁腳 ({“nt”: 4}) 也應該在輸出文件中,因此可以使用新記錄數對其進行編輯

輸出文件範例:

{"in": 5,"li": [{"st": 1508584161,"abc": 128416626,"ta": 33888}],"usr": {"is": "222108923573880","ie": "222108923573880"},"st2": 1508584161,"ei": {"ev": 0,"rt": 10},"rn": 947794,"st1": 1508584161} 
{"nt": 1}

我有以下內容:

jq -c 'select((.st1 &gt; 0 and .st2 &gt; 0 and .st1 &lt; .st2) or (.st1 &lt; 214748647 and .st2 &lt; 214748647 and .st1 &gt; 0 and .st2 &gt; 0 and .st1 &lt; .st2)) file.json

我嘗試了各種排列,但它沒有擷取正確的記錄。

使用正確的數字,您可以直接翻譯您的條件:

$ jq -c 'select(.st1 &lt;= .st2 and 
               .st1 &gt; 0 and .st2 &gt; 0 and 
               .st1 &lt; 2147483647 and .st2 &lt; 2147483647)' file.json 
{"in":5,"li":[{"st":1508584161,"abc":128416626,"ta":33888}],"usr":{"is":"222108923573880","ie":"222108923573880"},"st2":1508584161,"ei":{"ev":0,"rt":10},"rn":947794,"st1":1508584161}
{"in":5,"li":[{"st":1508584145,"abc":279682,"ta":50000}],"usr":{"is":"222108923573880","ie":"222108923573880"},"st2":1508584145,"ei":{"ev":0,"rt":18},"rn":947796,"st1":1508584145}

注意結束',並且沒有雙括號。我不明白你為什麼將條件分成兩個and由 連接的子句or,這不是你的條件所說的。

無論如何,這會擷取正確的記錄;現在我們只需要添加頁腳。這是最簡單的額外步驟,為簡潔起見,從上面縮短 select 子句:

jq -c 'select ...' file.json &gt; out.json
printf '{"nt":%i}\n' `wc -l &lt; out.json` &gt;&gt; out.json 

我想一個複雜的jq表達式也可以做到這一點,但我沒有嘗試過。

引用自:https://unix.stackexchange.com/questions/404699