LoginSignup
5
2

More than 3 years have passed since last update.

jqチートシート

Last updated at Posted at 2018-11-12

ほしい要素だけ抜き出す

jq '{name, description}'

指定した複数の要素をスペース区切りの文字列として出力する

jq -r '"\(.id_str) \(.text)"' < file

文字列のエスケープを解除して出力する

  • -rオプションを使う
エスケープされたまま
$ echo '{"key": "value\n\"aaaa\""}' | jq .key
"value\n\"aaaa\""
エスケープ解除
$ echo '{"key": "value\n\"aaaa\""}' | jq -r .key
value
"aaaa"

素の文字列を1行ずつJSON文字列にエスケープする

  • -Rを使う
$ printf '"aaa\nbbb cccc\tdddd' | jq -R
"\"aaa"
"bbb cccc\tdddd"

複数行の素の文字列を1つのJSON文字列にエスケープする

  • -R--slurpを使う
元の文字列
$ printf '"aaa\nbbb cccc\tdddd'
"aaa
bbb cccc    dddd
JSON文字列としてエスケープ
$ printf '"aaa\nbbb cccc\tdddd' | jq -R --slurp
"\"aaa\nbbb cccc\tdddd"

文字列に改行が含まれているJSONを扱う

例として以下のようなJSONがあったとします。

tweet.json
{
  "text": "遅れた!今描いた。\n\n#key\n#Kanon\n#水瀬名雪誕生祭\n#水瀬名雪誕生祭2019\n#12月23日は水瀬名雪の誕生日 https://t.co/zOGPbmBkwI",
  "id_str": "1209146623982366720",
  "source": "<a href=\"http://twitter.com/#!/download/ipad\" rel=\"nofollow\">Twitter for iPad</a>",
  "created_at": "Mon Dec 23 16:19:54 +0000 2019",
}

ほしい要素はtextid_strです。
安直に、jq -r '"\(.id_str) \(.text)"'とやると、

$ cat tweet.json | jq -r '"\(.id_str) \(.text)"'
1209146623982366720 遅れた!今描いた。

#key
#Kanon
#水瀬名雪誕生祭
#水瀬名雪誕生祭2019
#12月23日は水瀬名雪の誕生日 https://t.co/zOGPbmBkwI

このように\nがunescapeされてしまうので改行がはいってしまいます。

そこで、textに含まれる\n\x1fに置き換えることにしました。

repnl.sh
#!/bin/sh

RS="$(printf '\x1e')"
US="$(printf '\x1f')"

cat tweet.json                        |
jq -r '"\(.id_str) \(.text)'${RS}'"'  | # text の末尾にRSをつける
tr '\n' ${US}                         | # \n をUSで置換する
sed 's/'${RS}${US}'/'${RS}'/g'        | # RSとUSが連続している箇所をRSで置換する
tr -d '\n'                            | # grepが出力した末尾の \n を除去する
tr ${RS} '\n'                           # RSを \n で置換する

実行するとこんな感じになる。

$ ./repln.sh < tweet.json 
1209146623982366720 遅れた!今描いた。#key#Kanon#水瀬名雪誕生祭#水瀬名雪誕生祭2019#12月23日は水瀬名雪の誕生日 https://t.co/zOGPbmBkwI

textの内部の改行が単純に削除されているように見えるが、byte2hex(odとかでもよい)を使って1バイトずつ見てみると、1fというバイトが6個あるのがわかる。

$ ./repln.sh < tweet.json | byte2hex
.
.
.
81
9f
e3
80
82
1f  <-
1f  <-
23
6b
65
79
1f  <-
23
4b
61
6e
6f
6e
.
.
.

\x1fで置換した改行はtr $(printf '\x1f') '\n'で元の改行に戻せるので、例えばこんな感じで再利用ができる。

textの中の各行の先頭にidを付加する
$ ./repln.sh < tweet.json | while read -r l; do id="$(echo "${l}" | cut -d ' ' -f 1)"; echo "${l}" | cut -d ' ' -f 2 | tr $(printf '\x1f') '\n' | sed 's/^/'${id}' /'; done
1209146623982366720 遅れた!今描いた。
1209146623982366720 
1209146623982366720 #key
1209146623982366720 #Kanon
1209146623982366720 #水瀬名雪誕生祭
1209146623982366720 #水瀬名雪誕生祭2019
1209146623982366720 #12月23日は水瀬名雪の誕生日

条件にマッチした行だけ抽出する

文字列が一致

jq 'select(.id_str == "1213800636321390593")'

nullでないもの

jq 'select(.entities.media != null)'

配列を個々のオブジェクトに展開する

cat user_timeline.json | jq .[]

1オブジェクト1行で表示する

cat user_timeline.json | jq -c .[]

要素を追加する

jq --arg type "default" '. + {"type": $type}'
5
2
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
5
2