jq :在字段中生成 UUID

jq : Generate UUID in field

我需要用 UUID 唯一标记记录(用于关联 ID)。我看不到通过选项直接执行此操作的方法,这可能吗?如果没有,是否有某种解决方法可以做到这一点?

在 jq 中甚至可以生成随机数或字符串吗?

jq 目前不支持 UUID 生成,所以最好的办法是将 UUID 提供给 jq,例如按照这些思路:

ruby -e 'require "securerandom"; p SecureRandom.uuid' | jq '{uuid: .}'
{
  "uuid": "5657dd65-a495-4487-9887-c7f0e01645c9"
}

遗憾的是,jq 的 PRNG 贡献尚未进入正式版本。有关用 jq 编写的 PRNG 生成器的示例,请参见例如罗塞塔代码:

https://rosettacode.org/wiki/Linear_congruential_generator#jq

从无限的 UUID 流中读取

假设 uuidgen 等 uuid 生成器可用,您可以使用 inputinputs,如下所示:

jq -nR '[range(0;10) | input]' < <(while true; do uuidgen ; done)

(请注意,此处已避免使用 OS 管道。)

如果您提供一个个初始随机数(--argjson initialRandomNumber),则可以在jq中生成伪随机数。 传递 $RANDOM$RANDOM 而不是 $RANDOM 是为了增加初始伪随机值的范围。

我使用了 Rosettacode jq: random numbers 中函数 nextRandomNumber 的稍微修改版本 生成随机数、字符串和 UUID,如下面的代码所示。

每个函数都接受一个参数 $state 并在后续调用的响应中传递一个 newState

因为你问如何生成一个

  1. 随机数
  2. 随机字符串
  3. UUID

你可以在我的代码中找到 6 个函数来生成单个实例和它们的数组。

您可以在 jq 中选择您需要的功能并将其用作过滤器。

#!/bin/bash

jq -c -r -n --argjson initialRandomNumber "$RANDOM$RANDOM" '
  # 15-bit integers generated using the same formula as rand() from the Microsoft C Runtime.
  # The random numbers are in [0 -- 32767] inclusive.
  #
  # Input: 
  #   first call:      $state = a random number provided to jq by parameter
  #   subsequent call: $state = "newState" from last response
  #
  # Output: 
  #   object with pseudo-random number and "newState" for a subsequent call.
  def nextRandomNumber($state):
    ( (214013 * $state) + 2531011) % 2147483648 # mod 2^31
    | { newState: .,
        randomNumber: (. / 65536 | floor) };

  def nextRandomNumbers($state; $count):
    [foreach range($count) as $x (nextRandomNumber($state); nextRandomNumber(.newState); .)]
    | { newState: .[-1].newState,
        randomNumbers: map(.randomNumber) };


# ----- random UUID ---------------

  def hexByte:
    [. / 256 % 16, . % 16]
    | map(if . < 10 then . + 48 else . + 87 end)   # ASCII: 0...9: 48-57, a...f: 97-102
    | implode;

  def nextRandomUUID($state):
    nextRandomNumbers($state; 16)
    | .newState as $newState
    | .randomNumbers
    | map(hexByte)
    | "\(.[0:4] | join(""))-\(.[4:6] | join(""))-\(.[6:8] | join(""))-\(.[8:10] | join(""))-\(.[10:] | join(""))"
    | { newState: $newState,
        randomUUID: . };

  def nextRandomUUIDs($state; $count):
    [foreach range($count) as $x (nextRandomUUID($state); nextRandomUUID(.newState); .)]
    | { newState: .[-1].newState,
        randomUUIDs: map(.randomUUID) };


# ----- random String ---------------

  def letter:
    . % 52
    | [if . < 26 then . + 65 else . + 71 end]   # ASCII: A...Z: 65-90, a...z: 97-122
    | implode;

  def nextRandomString($state; $minLength; $maxLength):
    nextRandomNumber($state)
    | (try (.randomNumber % ($maxLength - $minLength + 1) + $minLength) catch $minLength) as $length
    | nextRandomNumbers(.newState; $length)
    | .newState as $newState
    | .randomNumbers
    | map(letter)
    | join("")
    | { newState: $newState,
        randomString: . };

  def nextRandomStrings($state; $count; $minLength; $maxLength):
    [foreach range($count) as $x (nextRandomString($state; $minLength; $maxLength); nextRandomString(.newState; $minLength; $maxLength); .)]
    | { newState: .[-1].newState,
        randomStrings: map(.randomString) };


# ----- example usage ---------------

  nextRandomNumber($initialRandomNumber)               # see output 1
# nextRandomNumbers($initialRandomNumber; 3)           # see output 2
# nextRandomUUID($initialRandomNumber)                 # see output 3
# nextRandomUUIDs($initialRandomNumber; 3)             # see output 4
# nextRandomString($initialRandomNumber; 10; 15)       # see output 5
# nextRandomStrings($initialRandomNumber; 3; 6; 10)    # see output 6
# nextRandomNumber($initialRandomNumber) | nextRandomNumbers(.newState; 3)   # see output 7
'

产出

output 1:生成伪随机数

{"newState":912028498,"randomNumber":13916}

output 2:生成3个伪随机数

{"newState":677282016,"randomNumbers":[10202,20943,6980]}`

output 3: 生成随机UUID

{"newState":1188119770,"randomUUID":"cdcda95b-af57-1303-da72-d21c6e7b1861"}

output 4: 生成3个随机UUID

{"newState":907540185,"randomUUIDs":["855c1445-b529-4301-a535-20cb298feaff","5b685e49-8596-830e-f56a-0a22c43c4c32","35fed6d8-d72b-2833-fd6f-f99154358067"]}

output 5:生成长度为10-15的随机字符串

{"newState":1037126684,"randomString":"SJadqPGkERAu"}`

output 6:生成3个长度为6-10

的随机字符串
{"newState":316121190,"randomStrings":["eNKxechu","XPkvNg","TIABHbYCxB"]}`

output 7: 使用newState进行第二次调用生成3个随机数

{"newState":808494511,"randomNumbers":[26045,16811,12336]}`