Warm tip: This article is reproduced from serverfault.com, please click

How to filter JSON array using JQ in shell (STRIPE)?

发布于 2021-04-28 17:39:50

Hello internet people,

Apparently I had the same problem of many but after searching a lot even here I could not find a reasonable answer at all!

My problem:

On shell I did enter the command: stripe invoices list --customer MY_CUSTOMER_ID_HERE

Then the following JSON appeared:

{
  "object": "list",
  "data": [
    {
      "id": "INVOICE_ID",
      "object": "invoice",
      "account_country": "COUNTRY",
      "account_name": "MY_BUSYNESS_NAME",
      "account_tax_ids": null,
      "amount_due": 1000,
      "amount_paid": 1000,
      "amount_remaining": 0,
      "application_fee_amount": null,
      "attempt_count": 1,
      "attempted": true,
      "auto_advance": false,
      "billing_reason": "subscription_create",
      "charge": "CHARGE_ID",
      "collection_method": "charge_automatically",
      "created": SOME_UNIXTIME,
      "currency": "usd",
      "custom_fields": null,
      "customer": "CUSTOMER_ID",
      "customer_address": null,
      "customer_email": "CUSTOMER_EMAIL",
      "customer_name": null,
      "customer_phone": "CUSTOMER_PHONE",
      "customer_shipping": null,
      "customer_tax_exempt": "none",
      "customer_tax_ids": [

      ],
      "default_payment_method": null,
      "default_source": null,
      "default_tax_rates": [

      ],
      "description": null,
      "discount": null,
      "discounts": [

      ],
      "due_date": null,
      "ending_balance": 0,
      "footer": null,
      "hosted_invoice_url": "INVOICE_URL_GOES_HERE",
      "invoice_pdf": "INVOICE_PDF_URL_GOES_HERE",
      "last_finalization_error": null,
      "lines": {
        "object": "list",
        "data": [
          {
            "id": "ID",
            "object": "line_item",
            "amount": 1000,
            "currency": "usd",
            "description": "PLAN_DESCRIPTION",
            "discount_amounts": [

            ],
            "discountable": true,
            "discounts": [

            ],
            "livemode": false,
            "metadata": {
            },
            "period": {
              "end": SOME_UNIXTIME,
              "start": SOME_UNIXTIME
            },
            "plan": {
              "id": "PRICE_ID_HERE",
              "object": "plan",
              "active": true,
              "aggregate_usage": null,
              "amount": 1000,
              "amount_decimal": "1000",
              "billing_scheme": "per_unit",
              "created": SOME_UNIXTIME,
              "currency": "usd",
              "interval": "month",
              "interval_count": 1,
              "livemode": false,
              "metadata": {
              },
              "nickname": null,
              "product": "PRODUCT_ID_HERE",
              "tiers_mode": null,
              "transform_usage": null,
              "trial_period_days": null,
              "usage_type": "licensed"
            },
            "price": {
              "id": "MORE_ID_HERE",
              "object": "price",
              "active": true,
              "billing_scheme": "per_unit",
              "created": SOME_UNIXTIME,
              "currency": "usd",
              "livemode": false,
              "lookup_key": null,
              "metadata": {
              },
              "nickname": null,
              "product": "PRODUCT_ID_HERE",
              "recurring": {
                "aggregate_usage": null,
                "interval": "month",
                "interval_count": 1,
                "trial_period_days": null,
                "usage_type": "licensed"
              },
              "tiers_mode": null,
              "transform_quantity": null,
              "type": "recurring",
              "unit_amount": 1000,
              "unit_amount_decimal": "1000"
            },
            "proration": false,
            "quantity": 1,
            "subscription": "SUBSCRIPTION_ID_HERE",
            "subscription_item": "SUBS_ITEM_ID_HERE",
            "tax_amounts": [

            ],
            "tax_rates": [

            ],
            "type": "subscription"
          }
        ],
        "has_more": false,
        "total_count": 1,
        "url": "IV_URL_HERE"
      },
      "livemode": false,
      "metadata": {
      },
      "next_payment_attempt": null,
      "number": "NUMBER_IV_XXXX",
      "on_behalf_of": null,
      "paid": true,
      "payment_intent": "PAYMENT_INTENT_ID_HERE",
      "payment_settings": {
        "payment_method_options": null,
        "payment_method_types": null
      },
      "period_end": SOME_UNIXTIME,
      "period_start": SOME_UNIXTIME,
      "post_payment_credit_notes_amount": 0,
      "pre_payment_credit_notes_amount": 0,
      "receipt_number": null,
      "starting_balance": 0,
      "statement_descriptor": null,
      "status": "paid",
      "status_transitions": {
        "finalized_at": SOME_UNIXTIME,
        "marked_uncollectible_at": null,
        "paid_at": SOME_UNIXTIME,
        "voided_at": null
      },
      "subscription": "SUBSCRIPTION_ID_HERE",
      "subtotal": 1000,
      "tax": null,
      "total": 1000,
      "total_discount_amounts": [

      ],
      "total_tax_amounts": [

      ],
      "transfer_data": null,
      "webhooks_delivered_at": SOME_UNIXTIME
    }
  ],
  "has_more": false,
  "url": "/some_path"
}

I'm able to access the second level with this command:

stripe invoices list --customer MY_CUSTOMER_ID_HERE | [.id,.attempt_count,.billing_reason,.created,.customer,.customer_email,.lines.data[],.paid,.status]'

Which returns a nice response, but I do want to filter few values inside data (data.lines.data[]) like id, plan and inside plan the id, currency and product for example.

My question:

Does any one knows how to do that with this kind of commands?


Just in case, those are the questions and answer that I tried but couldn't figured how to do it at all!

How to filter array of objects by element property values using jq?

How to filter arrays in json based on specific value using jq

How to filter nested arrays in JSON while maintaining structure using jq

filtering from JSON output from curl using JQ

Filtering JSON by object name using jq

How to filter JSON using jq stream (duplicate)

How to filter and replace values in json with jq

Filtering JSON list in shell using jq

I did also try a lot attempts on my own, like:

stripe invoices list --customer MY_CUSTOMER_ID_HERE | [.id,.attempt_count,.billing_reason,.created,.customer,.customer_email,.lines.data[.id.plan[][.id,.plan[.id,.currency,.product]],.paid,.status]'

Response: jq: error (at :179): Cannot index string with string "plan"

stripe invoices list --customer MY_CUSTOMER_ID_HERE | [.id,.attempt_count,.billing_reason,.created,.customer,.customer_email,.lines.data[][],.paid,.status]'

  • This one return a null value for the second data content.

Response:

[
  "DESIRED_ID",
  1,
  "value_retrieved_ok",
  unixtime_ok,
  "SOME_ID_OK",
  "customer_mail@ok.com",
  null, <<< ??? 
  true,
  "paid"
]

EDIT:

Desired result should look like:

[
  "DESIRED_ID",
  1,
  "value_retrieved_ok",
  unixtime_ok,
  "SOME_ID_OK",
  "customer_mail@ok.com",
  "id"             // the id inside lines.data{}
    ["id",         // the id inside lines.data.plan
     "currency",   // the currency inside lines.data.plan
     "product"     // the product inside lines.data.plan
    ]
  true,
  "paid"
]

Anyway I do hope that there's a good soul out there have mercy!

Questioner
luciela
Viewed
0
peak 2021-04-29 03:35:51

Your requirements are a bit difficult to follow, especially since the "expected output" does not correspond exactly to the given input, but the following is either what you're looking for, or very close to it:

.data[]
| [.id,.attempt_count,.billing_reason,.created,.customer,.customer_email]
  + (.lines.data[] | [.id, [.plan.id, .plan.currency, .plan.product]])
  + [.paid,.status]