ラベル jq の投稿を表示しています。 すべての投稿を表示
ラベル jq の投稿を表示しています。 すべての投稿を表示

2023年12月22日金曜日

Python から jq を使う方法

Python から jq を使う方法

概要

コマンドラインからではなく Python プログラム内で jq を使う方法を紹介します

環境

  • macOS 14.2
  • Python 3.11.6
  • jq.py 1.6.0

サンプルコード

import jq

# キーを指定して値を参照
a = {"name": "hawk", "age": 10}
print(jq.compile(".name").input_value(a).first())

# 配列をループして順番に参照
a = {"langs": ["ruby", "python", "javascript", "swift"]}
for lang in jq.compile(".langs[]").input_value(a):
    print(lang)

# 配列の長さを取得
a = {"langs": ["ruby", "python", "javascript", "swift", "elisp"]}
print(len(jq.compile(".langs[]").input_value(a).all()))

# all や first は参照した値の型を適切に返すが text は文字列として返す
print(type(jq.compile(".langs[]").input_value(a).all()))
print(type(jq.compile(".langs").input_value(a).text()))

上記をコマンドでやった場合

echo '{"name": "hawk", "age": 10}' | jq .name

echo '{"langs": ["ruby", "python", "javascript", "swift"]}' | jq '.langs[]'

echo '{"langs": ["ruby", "python", "javascript", "swift", "elisp"]}' | jq '.langs | length'

最後に

JSON のパースだけであれば Python デフォルトの json モジュールを使ってもできますが dict を直接扱うのが嫌な場合や複雑な場合には jq.py を使うことできれいに書けることがあるかもしれません

参考サイト

2022年4月14日木曜日

jq で配列の中の辞書内にある特定のカラムのみを CSV にする方法

jq で配列の中の辞書内にある特定のカラムのみを CSV にする方法

概要

CSV にするテクニックを紹介します

環境

  • macOS 11.6.5
  • jq 1.6

データ

  • vim test.json
{
  "user": {
    "codes": [
      {
        "name": "Ruby",
        "framework": "Rails"
      },
      {
        "name": "Swift",
        "framework": "SpriteKit"
      },
      {
        "name": "Python",
        "framework": "flask"
      }
    ]
  }
}

nameカラムを CSV にするコマンド

cat test.json | jq -r '[.user.codes[].name] | @csv'

ポイントは

  • 結果を [] で配列にする
  • @csv を使って配列を CSV として出力する

ちなみに更にここからダブルクオーテーションを削除したい場合はパイプで | sed 's/"//g' を追加します

2020年12月8日火曜日

jq で標準エラーをパイプする方法

概要

標準エラーは基本的にパイプできないので標準入力にリダイレクトしてあげましょう

環境

  • macOS 10.15.7
  • jq 1.5

動作する

  • echo '{"key":"value"}' | jq .

動作しない

  • ruby -e "STDERR.puts '{\"key\":\"value\"}'" | jq .

対処する

  • ruby -e "STDERR.puts '{\"key\":\"value\"}'" 2>&1 | jq .

2>&1 で標準エラーを標準リクエストにリダイレクトできます

おまけ: 標準エラーの tail -f を jq する場合は

  • ruby hoge.rb 2>&1 | while read line; do echo $line | jq -R '. as $line | try fromjson catch "not json"'; done

-R は入力された情報をパースせずにそのまま使用するオプションです
ダブルクォートなどが削除されません
as 変数格納で . で受け取った情報を $line という変数に格納して次のパイプで参照できるようにします
あとは try .. catch で受け取った $line を評価します
JSON ではない場合は「not json」が表示されます

テストスクリプトは以下です

loop do
  STDERR.puts '{"key":"value"}'
  STDERR.puts 'hoge'
  sleep(1)
end

参考サイト

2020年1月24日金曜日

jq で先頭のキー情報だけ出力する方法

概要

タイトルの通りです
jq を使ってキーの一覧がほしい場合に使える方法です

環境

  • jq 1.5

keys を使う

  • curl https://kaka-request-dumper.herokuapp.com | jq '.|keys'
[
  "body",
  "content_length",
  "form_data",
  "headers",
  "media_type",
  "method",
  "params",
  "path_info",
  "query_string"
]

更に特定のキーに対するキーの一覧を取得する場合は以下の通り

  • curl https://kaka-request-dumper.herokuapp.com | jq '.headers|keys'
[
  "HTTP_ACCEPT",
  "HTTP_CONNECTION",
  "HTTP_CONNECT_TIME",
  "HTTP_HOST",
  "HTTP_TOTAL_ROUTE_TIME",
  "HTTP_USER_AGENT",
  "HTTP_VERSION",
  "HTTP_VIA",
  "HTTP_X_FORWARDED_FOR",
  "HTTP_X_FORWARDED_PORT",
  "HTTP_X_FORWARDED_PROTO",
  "HTTP_X_REQUEST_ID",
  "HTTP_X_REQUEST_START"
]