JSONにコメントを書いて前処理で消す

# コメントのマイルール
コメントルールはとりあえずこれだけ。

- オブジェクトのカラム名が `#` で始まってたらそのカラムは削除する

で、jq の `walk` 関数を使って以下のようにしてやるとコメントカラムが綺麗に消えてくれます。

```shell-session
$ jq 'walk(if type == "object" then with_entries(select(.key[0:1] != "#")) else . end)' example.json
```



## 処理例
例えばこんなJSONがあったとします。

```example.json
{
  "Resources": {
    "AuroraDBParameterGroup": {
      "Type": "AWS::RDS::DBParameterGroup",
      "Properties": {
        "Parameters": {

          "# インデックスサイズ制限の緩和設定（Index column size too large. The maximum column size is 767 bytes. 対策）": null,
          "innodb_large_prefix": "1", "# インデックスのキープレフィクスを3072バイトまで拡張出来るようにする。有効にするには更に CERATE TABLE のプションで ROW_FORMAT=DYNAMIC を付けておく":null,
          "innodb_file_format": "Barracuda", "# これを使う為にはクラスタパラメータグループに binlog_format=MIXED を設定しておく必要もある":null,

          "# スローログ関連設定＞https://dev.mysql.com/doc/refman/5.6/ja/slow-query-log.html": null,
          "# 解析ツールは mysqldumpslow とか便利":null,
          "slow_query_log": "1", "# スロークエリーログを有効化。":null,
          "long_query_time": "1.0", "# 0-10の範囲でマイクロ秒まで指定可能、この指定秒数以上に時間がかかったクエリが記録されるようになる":null,
          "log_queries_not_using_indexes": "1", "# long_query_time以下でもインデックスを使っていないクエリは出力する":null,
          "log_output": "FILE", "# Auroraのスロークエリはデフォルトで TABLE (mysql.slow_log) に吐かれる。ストアドプロシージャの実行 (CALL mysql.rds_rotate_slow_log;) で mysql.slow_query_log テーブルにローテート出来る。":null

        },
        "Family": {"Ref": "AuroraFamily"},
        "Description": "Usual settings",
        "Tags": [{"Key": "Name", "Value": {"Ref": "AWS::StackName"}} ]
      }
    }
  }
}
```
↑これが、↓こうなる

```json:output　(実際はjq通した結果インデントが変わるけど比較しやすいよう体裁を修正してます)
{
  "Resources": {
    "AuroraDBParameterGroup": {
      "Type": "AWS::RDS::DBParameterGroup",
      "Properties": {
        "Parameters": {
          "innodb_large_prefix": "1",
          "innodb_file_format": "Barracuda",
          "slow_query_log": "1",
          "long_query_time": "1.0",
          "log_queries_not_using_indexes": "1",
          "log_output": "FILE"
        },
        "Family": {"Ref": "AuroraFamily"},
        "Description": "Usual settings",
        "Tags": [{"Key": "Name", "Value": {"Ref": "AWS::StackName"}} ]
      }
    }
  }
}
```

# walk が実装されてない問題❗ @v1.5

[jq のオンラインマニュアルに書いてある](https://stedolan.github.io/jq/manual/#walk(f))から使えるかと思って Example 実行すると

```
jq: error: walk/1 is not defined at <top-level>, line 1:
walk(if type == "array" then sort else . end)
jq: 1 compile error
```

とかってエラーが出る…。よくよく見たらオンラインマニュアルは Developer Version なのか。現時点で最新リリース番の[v1.5のマニュアル](https://stedolan.github.io/jq/manual/v1.5/)には確かに載っていない…。


## 自分で定義すれば使える！
しかし [walk function not work #963](https://github.com/stedolan/jq/issues/963) というIssueがあってそこで解決策が書いてあるので以下のコードを jq の式の先頭にコピペしてやればOK。

```jq
# Apply f to composite entities recursively, and to atoms
def walk(f):
  . as $in
  | if type == "object" then
      reduce keys[] as $key
        ( {}; . + { ($key):  ($in[$key] | walk(f)) } ) | f
  elif type == "array" then map( walk(f) ) | f
  else f
  end;
```

ところで jq スクリプト内に `行頭 #` で1行コメント書けるの初めて知ったわ。長いの書く時に便利に使っていこう。

## コメントカラムを消すスクリプト
walkの自前定義と最初の利用例を組み合わせて以下のようなスクリプトを作っておけば JSON からコメントを取り除くコマンドの完成だ。

```bash:jq-delete-comment.sh
#!/bin/bash

# walkはオンラインマニュアルに載ってるけどv1.5ではまだ未実装。
# しかし自分で定義すれば使える via https://github.com/stedolan/jq/issues/963
jq '
# Apply f to composite entities recursively, and to atoms
def walk(f):
  . as $in
  | if type == "object" then
      reduce keys[] as $key
        ( {}; . + { ($key):  ($in[$key] | walk(f)) } ) | f
  elif type == "array" then map( walk(f) ) | f
  else f
  end;

# コメントカラムを削除！
walk(if type == "object" then with_entries(select(.key[0:1] != "#")) else . end)
' "$@"
```

これを以下のように使えばコメントカラムが消せる！

```bash:
./jq-delete-comment.sh example.json
```

## 早く v1.6 をリリースしてほしい
です。