ほしい要素だけ抜き出す
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",
}
ほしい要素はtext
とid_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}'