[
{
"name": "user1",
"status": "off"
},
{
"name": "user2",
"status": "off"
},
{
"name": "user3",
"status": "on"
}
]
status
たとえば、JSONファイルから値を再帰的に取得し、状態のあるすべての値を取得off
する方法を知りたいと思います。name
off
user1
また、合計user2
値をどのように変更しますかon
?
私はとjq
を使用していますbash
。
ベストアンサー1
配列のすべての要素に式を適用して変更された配列を取得するには、を使用しますmap(expression)
。
状態のあるすべての項目を抽出しますoff
。
$ jq 'map(select(.status == "off"))' file
[
{
"name": "user1",
"status": "off"
},
{
"name": "user2",
"status": "off"
}
]
マッピングは、select(.status == "off")
次の要素のみを抽出(選択)して配列を変更します.status == "off"
。本物。
上記でデコードされた名前のみを抽出します。
$ jq -r 'map(select(.status == "off"))[].name' file
user1
user2
前の式の終わりに追加すると、[].name
最初に配列を個々の項目のセットに展開し(それがまさにその[]
操作です)、.name
各項目から値を抽出します。
また、使用することができます
jq -r 'map(select(.status == "off").name)[]' file
...名前配列を作成し、その配列からすべての要素を抽出します。
on
状態があるすべての項目の状態を次に設定しますoff
。
$ jq 'map(select(.status == "off").status = "on")' file
[
{
"name": "user1",
"status": "on"
},
{
"name": "user2",
"status": "on"
},
{
"name": "user3",
"status": "on"
}
]
マッピングを使用すると、状態を持つ要素の状態select(.status == "off").status = "on"
をに設定して配列を変更します。on
off
on
明示的な名前ベースのエントリの状態を次に設定します。
$ jq 'map(select(.name == "user1" or .name == "user2").status = "on")' file
[
{
"name": "user1",
"status": "on"
},
{
"name": "user2",
"status": "on"
},
{
"name": "user3",
"status": "on"
}
]
同じですが、式に名前をハードコードしないでください。代わりに、コマンドラインの最後にリストとして提供してください(--args
名前のリストは〜しなければならないコマンドラインの最後のエントリです):
$ jq 'map(select(IN(.name; $ARGS.positional[])).status = "on")' file --args user1 user2
[
{
"name": "user1",
"status": "on"
},
{
"name": "user2",
"status": "on"
},
{
"name": "user3",
"status": "on"
}
]
指定された名前のリストは、名前付き--args
配列にあります$ARGS.positional
。
状況がIN(a; b)
戻ってきました。本物a
セットにいる場合b
。$ARGS.positional[]
コマンドラインで指定された名前のセットである検索セットとして使用します。つまり、select()
ここではコマンドラインリストに名前が表示される要素のみを抽出し、これらの要素の状態はに設定されますon
。
IN(a; b)
同様の名前の項目とは異なり、次in(a)
を返します。本物与えられた値がオブジェクトまたは配列のキーまたはインデックスとして表示される場合a
。
環境みんな項目の状態は次のとおりですon
。
$ jq 'map(.status = "on")' file
[
{
"name": "user1",
"status": "on"
},
{
"name": "user2",
"status": "on"
},
{
"name": "user3",
"status": "on"
}
]
コメントの次の質問:
このようにマッチングしたい場合は
NOT IN(a, b)
どうすればよいですか?明らかに私が尋ねるのは、このような値を渡すと、それ以外のすべてがuser1
オフになるということですuser1
。どうすればいいですか?
以下は、明示的なステートメントを使用して、if
特定の名前の状態を次のように変更します。on
off
jq '
map(
if IN(.name; $ARGS.positional[]) then
.status = "on"
else
.status = "off"
end
)' file --args user1
または、単一行レイアウトでは、次のことを行います。
jq 'map(if IN(.name; $ARGS.positional[]) then .status = "on" else .status = "off" end)' file --args user1
フォローアップを次のように解釈すると、いいえ状態に関係なく、特定の名前の状態を変更したいのですが、他のすべての状態はに変更したいと思いますoff
。この場合、以前のバリエーションで使用されていた条件を無効にすることができます。
jq 'map(select(IN(.name; $ARGS.positional[]) | not).status = "off")' file --args user1
| not
後で追加された内容を参照してくださいIN(...; ...)
。
もちろん、if
上記のほとんどのバリエーションでステートメントを使用することもできますが、select()
可能であればそれを使用するのが好きです。