シェル芸でJSONが作りたい
JSON形式のファイルを要求するCLIツールを利用する際や、簡単なWebAPIとして静的なJSONファイルを配信するような場合、コマンドラインから簡単にJSONファイルが作れると便利です。
一番簡単な方法
雑に以下のようなコマンドでも目的は達成できます。
$ echo "{\"test\": \"`date`\"}" > date.json
できてますね
$ cat date.json
{"test": "2021年 12月 8日 水曜日 15時40分59秒 JST"}
しかし、コマンドの実行結果に ダブルクォートや改行が含まれる場合は、話がややこしくなります。
シェル芸といえばsedなどがパッと思いつきますが、sedでJSONのエスケープ処理を頑張って記述するのも面倒です。
そうだjqを使おう
シェル芸としては邪道かもしれませんが、餅は餅屋ということで、JSON周りの処理はjqに任せてみることにしましょう。
jqは**「既に存在するJSON形式のファイルからその要素を取り出す」**という目的で使うことが多いですが、今回のように何もないところからJSON形式のファイルを作る時にも利用できます。
# いわゆる普通のjqの使い方
$ cat date.json|jq -r '.test'
2021年 12月 8日 水曜日 15時40分59秒 JST
# -n(--nill-input)で入力なしでjsonを処理できる、加えて代入でjsonに要素を追加できる
$ jq -n '.test = "hoge"'
{
"test": "hoge"
}
jqでJSONエスケープ
jqは--arg
を使うことで、変数を定義できます。
$ jq --arg variable hoge -n '.test = $variable'
{
"test": "hoge"
}
この変数の中にJSONエスケープが必要な文字が入っている場合はjqがうまいことエスケープしてくれます。
$ jq --arg variable 'ho"ge' -n '.test = $variable'
{
"test": "ho\"ge"
}
ここまでくればあとは簡単です。
実行したいコマンドをjqの引数として渡すことで、JSONのエスケープのことはjqに任せてJSON形式で出力できます。
(treeコマンドをそのままJSONの要素に入れることが実際にあるかは謎ですが・・)
$ jq --arg tree "`tree`" -n '.test = $tree'
{
"test": ".\n├── date.json\n├── hello.txt\n└── world.txt\n\n0 directories, 3 files"
}
参考