Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
8
Help us understand the problem. What is going on with this article?
@kawaz

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

More than 3 years have passed since last update.

コメントのマイルール

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

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

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

$ 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"}} ]
      }
    }
  }
}

↑これが、↓こうなる

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 のオンラインマニュアルに書いてあるから使えるかと思って 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のマニュアルには確かに載っていない…。

自分で定義すれば使える!

しかし walk function not work #963 というIssueがあってそこで解決策が書いてあるので以下のコードを jq の式の先頭にコピペしてやればOK。

# 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 からコメントを取り除くコマンドの完成だ。

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)
' "$@"

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

./jq-delete-comment.sh example.json

早く v1.6 をリリースしてほしい

です。

8
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
8
Help us understand the problem. What is going on with this article?