json 从jq中的列表中选择随机id并更新值

dluptydi  于 2023-05-08  发布在  其他
关注(0)|答案(3)|浏览(148)

我有一些我要接收的样本有效载荷,它看起来像这样:

[
  {
    "Id": "9",
    "Line": [
      {
        "Amount": 100,
        "Description": "Weekly Gardening Service",
        "DetailType": "SalesItemLineDetail",
        "Id": "1",
        "LineNum": 1,
        "SalesItemLineDetail": {
          "ItemAccountRef": {
            "name": "Landscaping Services",
            "value": "45"
          },
          "ItemRef": {
            "name": "Gardening",
            "value": "6"
          },
          "Qty": 4,
          "TaxCodeRef": {
            "value": "TAX"
          },
          "UnitPrice": 25
        }
      },
      {
        "Amount": 100,
        "DetailType": "SubTotalLineDetail",
        "SubTotalLineDetail": {}
      }
    ]
  },
  {
    "Id": "10",
    "Line": [
      {
        "Amount": 140,
        "Description": "Weekly Gardening Service",
        "DetailType": "SalesItemLineDetail",
        "Id": "1",
        "LineNum": 1,
        "SalesItemLineDetail": {
          "ItemAccountRef": {
            "name": "Landscaping Services",
            "value": "45"
          },
          "ItemRef": {
            "name": "Gardening",
            "value": "6"
          },
          "Qty": 4,
          "TaxCodeRef": {
            "value": "NON"
          },
          "UnitPrice": 35
        }
      },
      {
        "Amount": 35,
        "Description": "Pest Control Services",
        "DetailType": "SalesItemLineDetail",
        "Id": "2",
        "LineNum": 2,
        "SalesItemLineDetail": {
          "ItemAccountRef": {
            "name": "Pest Control Services",
            "value": "54"
          },
          "ItemRef": {
            "name": "Pest Control",
            "value": "10"
          },
          "Qty": 1,
          "TaxCodeRef": {
            "value": "NON"
          },
          "UnitPrice": 35
        }
      },
      {
        "Amount": 175,
        "DetailType": "SubTotalLineDetail",
        "SubTotalLineDetail": {}
      }
    ]
  }
]

这些我知道是有效的,我需要交叉引用他们,通过id,在另一个有效载荷我收到。但是,我收到的数据,我不能假设有有效的ID的。
因此,我想从上面获取所有有效的Id,并将它们随机放入我的样本数据中,看起来像这样的($.invoices[].qbId)

[
  {
    "id": "fb2430c5-5970-46b0-9947-aaa0b9f177bb",
    "invoices": [
      {
        "description": "2022-02-03 - 179",
        "dueDate": "2022-02-03T22:51:10.206Z",
        "id": "6f904b18-71c6-4fec-a016-7452f6a6b1dc",
        "invoiceDate": "2022-02-03T22:51:10.347Z",
        "openBalance": 200,
        "paidAmount": 200,
        "qbId": "1",
        "totalAmount": 212
      }
    ]
  },
  {
    "id": "fa5b77b5-bfd4-4178-ac31-386ec83f530c",
    "invoices": [
      {
        "description": "2022-01-12 - 95",
        "dueDate": "2022-01-12T14:08:26.219Z",
        "id": "05a58be3-4396-4c15-b9c2-ece68cb2b3fb",
        "invoiceDate": "2022-01-12T14:08:26.399Z",
        "openBalance": 7.33,
        "paidAmount": 7.33,
        "qbId": "",
        "totalAmount": 7.33
      },
      {
        "description": "2022-01-12 - 95",
        "dueDate": "2022-01-12T14:08:26.219Z",
        "id": "91f5ecd0-e18d-4029-8745-143323e02007",
        "invoiceDate": "2022-01-12T14:08:26.580Z",
        "openBalance": 53.13,
        "paidAmount": 53.13,
        "qbId": "",
        "totalAmount": 53.13
      }
    ]
  }
]

这个JQ将得到我的IDsjq '.QueryResponse.Invoice | map(.Id)',其可以容易地被JQ消耗。现在的问题是(这是我不知道的)如何从这个数组中随机选择并更新示例负载:

jq 'map(. + {
   invoices : .invoices | map(. + {qbId: ??random here })
   })
'
nhjlsmyf

nhjlsmyf1#

如果我理解正确的话,您希望用随机生成的id字符串替换每个id字段(拼写可能不同,有时是Id)。
该解决方案首先使用jq提取所有此类id字段(以各种拼写)的路径,然后在shell中迭代结果,使用uuidgen为每个字段生成一个id,该id被馈送到另一个jq调用中,该调用使用setpath更改保存到生成的id的路径处的值:

file="input.json"

jq -c '
  paths(.. | scalars) | select(.[-1] == ("id", "Id", "ID")) | tojson
' "$file" |
while read -r json; do printf '["%s",%s]\n' "$(uuidgen)" "$json"; done |
jq -n --argfile file "$file" '
  reduce inputs as [$id,$json] ($file; setpath($json | fromjson; $id))
'
[
  {
    "Id": "10162eb7-29ba-4b60-ad20-e5b1133eca63",
    "Line": [
      {
        "Amount": 100,
        "Description": "Weekly Gardening Service",
        "DetailType": "SalesItemLineDetail",
        "Id": "272832df-a8f5-4877-92de-1545150afc33",
        "LineNum": 1,
        "SalesItemLineDetail": {
          "ItemAccountRef": {
            "name": "Landscaping Services",
            "value": "45"
          },
          "ItemRef": {
            "name": "Gardening",
            "value": "6"
          },
          "Qty": 4,
          "TaxCodeRef": {
            "value": "TAX"
          },
          "UnitPrice": 25
        }
      },
      {
        "Amount": 100,
        "DetailType": "SubTotalLineDetail",
        "SubTotalLineDetail": {}
      }
    ]
  },
  {
    "Id": "190b0e50-e007-46a4-b1ca-c3efb762629c",
    "Line": [
      {
        "Amount": 140,
        "Description": "Weekly Gardening Service",
        "DetailType": "SalesItemLineDetail",
        "Id": "f7067227-56d4-4849-873a-3ee5c336999e",
        "LineNum": 1,
        "SalesItemLineDetail": {
          "ItemAccountRef": {
            "name": "Landscaping Services",
            "value": "45"
          },
          "ItemRef": {
            "name": "Gardening",
            "value": "6"
          },
          "Qty": 4,
          "TaxCodeRef": {
            "value": "NON"
          },
          "UnitPrice": 35
        }
      },
      {
        "Amount": 35,
        "Description": "Pest Control Services",
        "DetailType": "SalesItemLineDetail",
        "Id": "181d7c6b-0afa-4f44-a568-2c482fc5c285",
        "LineNum": 2,
        "SalesItemLineDetail": {
          "ItemAccountRef": {
            "name": "Pest Control Services",
            "value": "54"
          },
          "ItemRef": {
            "name": "Pest Control",
            "value": "10"
          },
          "Qty": 1,
          "TaxCodeRef": {
            "value": "NON"
          },
          "UnitPrice": 35
        }
      },
      {
        "Amount": 175,
        "DetailType": "SubTotalLineDetail",
        "SubTotalLineDetail": {}
      }
    ]
  }
]
tv6aics1

tv6aics12#

下面是我使用'now'作为random的源来创建随机日期字符串的代码片段。使用数组长度作为上限,在id数组(map)中生成索引应该很简单:

#!/bin/sh
echo "{}" | jq '
    (now * 1000000) as $random |
    (($random * 3) % 10 + 2015 | tostring) as $year |
    (($random * 5) % 12 + 1 | tostring | ("0" + .) | .[0:2]) as $month |
    (($random * 7) % 28 + 1 | tostring | ("0" + .) | .[0:2]) as $day |
    ($year + "-" + $month + "-" + $day) as $randomDate |
    {randomDate: $randomDate}
'
llew8vvj

llew8vvj3#

这展示了如何从数组中随机选择元素,假设一个bash或足够类似bash的环境:

#!/bin/bash

< /dev/urandom tr -cd '0-9' | fold -w 1 | jq -MRnc '

# Output: a prn in range(0;$n) where $n is `.`
def prn:
  if . == 1 then 0
  else . as $n
  | ([1, (($n-1)|tostring|length)]|max) as $w
  | [limit($w; inputs)] | join("") | tonumber
  | if . < $n then . else ($n | prn) end
  end;

# Input: an array
# Output: an array, being a selection of $k elements from . chosen at random without replacement
def prns($k):
  if $k <= 0 then []
  else . as $in
  | length as $n
  | if $k > $n then "no can do" | error
    else ($n|prn) as $ix
    | [$in[$ix]] + (($in[0:$ix] + $in[$ix+1:])|prns($k-1))
    end
  end;

# Two illustrations
# Three from range(0,10) (with replacement):
[range(0;10) | ( ["a", "b", "c"] | .[length|prn]) ],

# Three from an array, without replacement:
([range(0;10)] | prns(3))

'

相关问题