0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

jqコマンドでカジュアルに○○する

0
Posted at

はじめに

jsonをモニョモニョするのにjqというツールがありますが、使い始めるとAPI確認したり叩いたりするのにとても役に立ちます。
自分は大体以下のようなときに使います。

  • jsonを見やすくする(本記事対象外)
  • indentedなjsonを一行にする(jq -c .
  • jsonをパラメータに引き渡す/結果から取り出すための前処理をする
    • jsonの中に文字列としてjsonフォーマットのデータを入れる(jq '. | @json'
    • jsonの中からjsonを取り出す(jq '. | fromjson
  • jqコマンドの結果(の一部)を変数に格納する

対象文字列の用意

jsonのサンプルは以下から拝借。
https://www.ibm.com/support/knowledgecenter/ja/SS9H2Y_7.5.0/com.ibm.dp.doc/json_jsonexamples.html

以下の通り。

text_ship_to=$(cat << EOF
{ "name" : "Jane Smith",
  "address" : "123 Maple Street",
  "city" : "Pretendville",
  "state" : "NY",
  "zip"   : "12345"
}
EOF
)

text_bill_to=$(cat << EOF
{ "name" : "John Smith",
  "address" : "123 Maple Street",
  "city" : "Pretendville",
  "state" : "NY",
  "zip"   : "12345"
}
EOF
)

text_base=$(cat << EOF
{ "name"   : "John Smith",
  "sku"    : "20223",
  "price"  : 23.95,
  "shipTo" : ${text_ship_to},
  "billTo" : ${text_bill_to}
}
EOF
)

echo $text_base した結果がこんなかんじ。

text_base
{ "name"   : "John Smith",
  "sku"    : "20223",
  "price"  : 23.95,
  "shipTo" : { "name" : "Jane Smith",
  "address" : "123 Maple Street",
  "city" : "Pretendville",
  "state" : "NY",
  "zip"   : "12345"
},
  "billTo" : { "name" : "John Smith",
  "address" : "123 Maple Street",
  "city" : "Pretendville",
  "state" : "NY",
  "zip"   : "12345"
}
}

操作

indentedなjsonを一行にする(jq -c .

$text_baseはインデントの入ったprettyなjsonなので、これをcomapctにしてみる。

bash
json_text=$(echo $text_base| jq -c .)

ヒアドキュメントを直接渡す場合は、jq<< する。

bash
json_text=$(jq -c . << EOF
{ "name"   : "John Smith",
  "sku"    : "20223",
  "price"  : 23.95,
  "shipTo" : { "name" : "Jane Smith",
               "address" : "123 Maple Street",
               "city" : "Pretendville",
               "state" : "NY",
               "zip"   : "12345" },
  "billTo" : { "name" : "John Smith",
               "address" : "123 Maple Street",
               "city" : "Pretendville",
               "state" : "NY",
               "zip"   : "12345" }
}
EOF
)

結果はこんなかんじ

bash
$ json_text=$(echo $text_base| jq -c .)
$ echo $json_text
{"name":"John Smith","sku":"20223","price":23.95,"shipTo":{"name":"Jane Smith","address":"123 Maple Street","city":"Pretendville","state":"NY","zip":"12345"},"billTo":{"name":"John Smith","address":"123 Maple Street","city":"Pretendville","state":"NY","zip":"12345"}}

jsonをパラメータに引き渡す/結果から取り出すための前処理をする

自分はおもに、AWS CLIでIAM設定するときのPolicyDocumentなど、json形式の引数をjsonの中に埋めたり出したりするのに使います。

jsonの中に文字列としてjsonフォーマットのデータを入れる(jq '. | @json'

jsonの中に文字列としてjsonを入れるため、試しに以下をエスケープする。

bash
# エスケープ
escaped_text_ship_to=$(echo $text_ship_to | jq '. | @json')
escaped_text_bill_to=$(echo $text_bill_to | jq '. | @json')

escaped_text_* をechoしてみると、@jsonな(jsonの中に入れられる)形式にエスケープされていることが分かる。

bash
echo $escaped_text_ship_to
echo $escaped_text_bill_to
$escaped_text_ship_to
"{\"name\":\"Jane Smith\",\"address\":\"123 Maple Street\",\"city\":\"Pretendville\",\"state\":\"NY\",\"zip\":\"12345\"}"
$escaped_text_bill_to
"{\"name\":\"John Smith\",\"address\":\"123 Maple Street\",\"city\":\"Pretendville\",\"state\":\"NY\",\"zip\":\"12345\"}"

baseに入れてみる。

escaped_text_base=$(cat << EOF
{ "name"   : "John Smith",
  "sku"    : "20223",
  "price"  : 23.95,
  "shipTo" : ${escaped_text_ship_to},
  "billTo" : ${escaped_text_bill_to}
}
EOF
)

echo $escaped_text_base | jq してみた結果。shipTobillToがエスケープされたjsonになってる。

$escaped_text_base
{
  "name": "John Smith",
  "sku": "20223",
  "price": 23.95,
  "shipTo": "{\"name\":\"Jane Smith\",\"address\":\"123 Maple Street\",\"city\":\"Pretendville\",\"state\":\"NY\",\"zip\":\"12345\"}",
  "billTo": "{\"name\":\"John Smith\",\"address\":\"123 Maple Street\",\"city\":\"Pretendville\",\"state\":\"NY\",\"zip\":\"12345\"}"
}

jsonの中に文字列として入っているjsonフォーマットのデータを取り出す(jq '. | fromjson'

$escaped_text_baseのjsonの中のshipToはエスケープされている。

bash
# shipToを取り出してみる

echo $escaped_text_base | jq '.shipTo'
.shipTo
"{\"name\":\"Jane Smith\",\"address\":\"123 Maple Street\",\"city\":\"Pretendville\",\"state\":\"NY\",\"zip\":\"12345\"}"

これを| fromjsonを使ってunescapeしてみる。

bash
echo $escaped_text_base | jq '.shipTo | fromjson'

以下のように取れる。

fromjson
{
  "name": "Jane Smith",
  "address": "123 Maple Street",
  "city": "Pretendville",
  "state": "NY",
  "zip": "12345"
}

jqコマンドの結果(の一部)を変数に格納する

AWS CLIでコマンド叩いた結果からIdだけ引っ張ってくるのに使ったりします。

まずは対象データの準備。

bash
input='"{\"name\":\"Jane Smith\",\"address\":\"123 Maple Street\",\"city\":\"Pretendville\",\"state\":\"NY\",\"zip\":\"12345\"}"'
echo $input
target
"{\"name\":\"Jane Smith\",\"address\":\"123 Maple Street\",\"city\":\"Pretendville\",\"state\":\"NY\",\"zip\":\"12345\"}"

この $inputjqにかけて結果を変数に入れます。たとえばstateをダブルクオートなしで取り出す。

bash
state=$(echo $input| jq 'fromjson | .state' | sed -e 's/"//g')
echo $state
$state
NY
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?