やりたい事
JSONファイルの編集をしてて、ケツカンマのデータを作ってしまって読めないって怒られる。
ありますよね。
{
"field_1": [
"a",
"b",
"c",
],
"field_2": {
"a":0,
"b":1,
"c":2,
},
}
$ cat invalid_json.json | jq .
parse error: Expected another array element at line 6, column 3
このケースだと、以下の3箇所のカンマが不要です。
"c",
"c":2,
},
プログラムから出力する場合も、JSONをサポートしていない言語とかだとぶっちゃけちゃんと出力するのもめんどくさい。
これをワンライナーで整形したい。
※jqにその整形オプションがあるかと思ったのですが、jqは上記の不正ファイルは食べてくれないようです。
前提条件
jq がインストールされている環境であること。
結論
ケツカンマを雑に削除してからjqに再度食わせて整形すればOK
$ cat invalid_json.json | sed -z -r 's/,\n?[ \t]*([]}])/\1/g' | jq .
{
"field_1": [
"a",
"b",
"c"
],
"field_2": {
"a": 0,
"b": 1,
"c": 2
}
}
解説
sed でケツカンマ部分を検出して雑に削除しています。
$ cat invalid_json.json | sed -z -r 's/,\n?[ \t]*([]}])/\1/g'
{
"field_1": [
"a",
"b",
"c"],
"field_2": {
"a":0,
"b":1,
"c":2}}
sed オプション
-z : 改行を含む複数行での検出を実施
-r : 正規表現検出
検出対象文字列の解説
sedに指定したこの部分で、置換対象の文字列を検出しています。
,\n?[ \t]*([]}])
カンマがあること
,\n?[ \t]*([]}])
その次に改行があったりなかったりすること
,\n?[ \t]*([]}])
その次にホワイトスペースまたはタブがあったりなかったりすること
,\n?[ \t]*([]}])
その次に"]"または"}"で閉じられていること
※後で後方参照で利用するために、 () で囲っています。
,\n?[ \t]*([]}])
置換文字列の解説
対象文字列の検出で検出された閉じカッコと同じカッコに置換します。
このとき、途中の改行やホワイトスペースは全て削除されますが、jqはそんなことは気にしませんので、最後にjqに食わせて再整形します。
\1
何もかもめんどくさい人に
こういったワンライナーはalias登録しておくのが便利です。
以下のエイリアスを ~/.bashrc や ~/.profile に登録しておきましょう。(私はWSL2を使っているので、.profileに登録しました。)
,,, 中略
alias jsonlint="sed -z -r 's/,\n?[ \t]*([]}])/\1/g' | jq ."
使い方
$ cat invalid_json.json | jsonlint
{
"field_1": [
"a",
"b",
"c"
],
"field_2": {
"a": 0,
"b": 1,
"c": 2
}
}
ファイルそのものを整形したければ、
$ cat invalid_json.json | jsonlint > invalid_json.json
でOKです。