jqコマンドで値をキーとしたオブジェクトに整形する方法

ひと工夫必要だったのでメモ。

やりたいこと

jq コマンドを使って値をキーとしたオブジェクトに整形したい。具体例を挙げると以下のようなイメージ。

{
  "name": "taro",
  "age": 20,
  "info": ["hoge", "fuga"]
}

上のような JSON を、下のように加工したい。

{
  "taro": ["hoge", "fuga"]
}

jq では取得した値をオブジェクトのキーにできない

検証環境は次の通り。

$ jq -V
jq-1.6

単純に取得した値をキーとすれば良さそうだが、エラーとなってしまう。

$ echo '{"name":"taro","age":20,"info":["hoge", "fuga"]}' | jq '. | {.name: .info}'
jq: error: syntax error, unexpected FIELD (Unix shell quoting issues?) at <top-level>, line 1:
. | {.name: .info}
jq: error: May need parentheses around object key expression at <top-level>, line 1:
. | {.name: .info}
jq: 2 compile errors

解決方法

(追記)Twitter で簡単な方法を教えていただきました。

echo '{"name":"taro","age":20,"info":["hoge", "fuga"]}' | jq '. | {(.name): .info}'

別解

キーとしたい値を使って適当なオブジェクトを作り、そこから値を取得する。

$ echo '{"name":"taro","age":20,"info":["hoge", "fuga"]}' | jq '. | {({name: .name} | to_entries[] | .value): .info}'
{
  "taro": [
    "hoge",
    "fuga"
  ]
}

次のような書き方もできる。

$ echo '{"name":"taro","age":20,"info":["hoge", "fuga"]}' | jq '. | .name as $name | {({$name} | to_entries[] | .value): .info}'
{
  "taro": [
    "hoge",
    "fuga"
  ]
}

参考にしたページ

jq Manual (development version)