web-dev-qa-db-ja.com

JSONオブジェクトをjqのkey = value形式に変換する方法は?

Jqでは、JSONをkey=valueの文字列に変換するにはどうすればよいですか?

から:

{
    "var": 1,
    "foo": "bar",
    "x": "test"
}

に:

var=1
foo=bar
x=test
36
gianebao

あなたは試すことができます:

jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]' test.json

ここにデモがあります:

$ cat test.json
{
    "var": 1,
    "foo": "bar",
    "x": "test"
}
$ jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]' test.json
foo=bar
var=1
x=test
56
aioobe

これを再帰的に行う方法はありますか?

ここにあなたが望むことをするかもしれない関数があります:

# Denote the input of recursively_reduce(f) by $in.
# Let f be a filter such that for any object o, (o|f) is an array.
# If $in is an object, then return $in|f;
# if $in is a scalar, then return [];
# otherwise, collect the results of applying recursively_reduce(f)
# to each item in $in.
def recursively_reduce(f):
  if type == "object" then f
  Elif type == "array" then map( recursively_reduce(f) ) | add
  else []
  end;

例:key = valueペアを発行する

def kv: to_entries | map("\(.key)=\(.value)");


[ {"a":1}, [[{"b":2, "c": 3}]] ] | recursively_reduce(kv)
#=> ["a=1","b=2","c=3"]

更新:jq 1.5のリリース後、jq定義の組み込みとしてwalk/1が追加されました。上記で定義されたkvで使用できます。次のように:

 walk(if type == "object" then kv else . end) 

上記の入力では、結果は次のようになります。

[["a = 1"]、[[["b = 2"、 "c = 3"]]]]

出力を「平坦化」するには、flatten/0を使用できます。以下は完全な例です。

jq -cr 'def kv: to_entries | map("\(.key)=\(.value)");
        walk(if type == "object" then kv else . end) | flatten[]'

入力:

[ {"a":1}, [[{"b":2, "c": 3}]] ]

出力:

a=1
b=2
c=3
5
peak

ちなみに、@ aioobeの素晴らしい答えを基にしています。キーをすべて大文字にする必要がある場合は、ascii_upcaseを使用して、彼の例を変更することでこれを行うことができます。

jq -r 'to_entries|map("\(.key|ascii_upcase)=\(.value|tostring)")|.[]'

私はあなたのシナリオに似たシナリオを持っていましたが、AWSにアクセスするための環境変数を作成するときにすべてのキーを大文字にしたいと思いました。

$ okta-credential_process arn:aws:iam::1234567890123:role/myRole | \
     jq -r 'to_entries|map("\(.key|ascii_upcase)=\(.value|tostring)")|.[]'
EXPIRATION=2019-08-30T16:46:55.307014Z
VERSION=1
SESSIONTOKEN=ABcdEFghIJ....
ACCESSKEYID=ABCDEFGHIJ.....
SECRETACCESSKEY=AbCdEfGhI.....

参考文献

1
slm

jqがなければ、grepsedを使用してjsonのすべてのアイテムをエクスポートできましたが、これはキーと値のペアがある場合にのみ簡単なケースで機能します

for keyval in $(grep -E '": [^\{]' fileName.json | sed -e 's/: /=/' -e "s/\(\,\)$//"); do
    echo "$keyval"
done

ここにサンプルの応答があります:

❯ for keyval in $(grep -E '": [^\{]' config.dev.json | sed -e 's/: /=/' -e "s/\(\,\)$//"); do
    echo "$keyval"       
done
"env"="dev"
"memory"=128
"role"=""
"region"="us-east-1"
0