使用 Json 的 Value 作为变量 x 次

使用 Json 的 Value 作为变量 x 次

我有一个 json 文件,其中包含其条目列表的 id

[
    {
        "list_id": 1,
        "list_key": "gnfijgndngd458wjfisdnfpon",
        "entries": 0
    },
    {
        "list_id": 2,
        "list_key": "gnfijgndndfp[mfphm,]ordjkt9roh,mkn",
        "entries": 0
    },
    {
        "list_id": 3,
        "list_key": "gnfijgnsnfc0wr8envpuh-[sijjnhmgmvisbfusf",
        "entries": 0
    }
]

每个的最大条目数等于 100。这意味着我只能使用一个 list_id 100 次。

如何在 bash 脚本中使用这些 id 作为变量?就像 100 个条目之后,它应该更改为另一个 list_id

答案1

要获取list_id顶级匿名数组中值entries小于 100 的第一个元素,您可以使用

jq 'map(select(.entries < 100)) | first.list_id' file

(这将返回一个整数,即list_id值。)

要将entries值加一,

jq 'map(select(.entries < 100)) | first.entries += 1' file

或者,如果您有一个特定的值list_id,您希望增加其entires值,假设每个值list_id都是唯一的,

jq --argjson list_id "$list_id" 'map(select(.list_id == $list_id).entries += 1)' file

(这些返回更新的文档。)

因此,在您的 shell 脚本中:

# get list_id
list_id=$( jq 'map(select(.entries < 100)) | first.list_id' file )

# check whether we got the string "null" back, which indicates
# that we found no entry ith "entries" less than 100
if [ "$list_id" = null ]; then
    echo 'No list_id with entries < 100 available' >&2
    exit 1
fi

# increment counter (in-place edit using GNU sponge)
jq --argjson list_id "$list_id" 'map(select(.list_id == $list_id).entries += 1)' file | sponge file

运行上述脚本 110 次后,中的 JSON 文档file将等效于以下内容(假设所有entries计数器都从零开始):

[
   { "entries": 100, "list_id": 1, "list_key": "gnfijgndngd458wjfisdnfpon" },
   { "entries": 10, "list_id": 2, "list_key": "gnfijgndndfp[mfphm,]ordjkt9roh,mkn" },
   { "entries": 0, "list_id": 3, "list_key": "gnfijgnsnfc0wr8envpuh-[sijjnhmgmvisbfusf" }
]

如果list_id值严格非零,则可以通过使用jq-e( --exit-status) 选项来缩短上述 shell 脚本:

if ! list_id=$( jq -e 'map(select(.entries < 10)) | first.list_id' file )
then
    echo 'No list_id with entries < 100 available' >&2
    exit 1
fi

# increment counter (in-place edit using GNU sponge)
jq --argjson list_id "$list_id" 'map(select(.list_id == $list_id).entries += 1)' file | sponge file

请注意,上述代码均未尝试执行任何文件锁定,并且如果两个或多个并发进程运行该脚本,则代码中存在明显的竞争条件(因为list_id计数器的获取和更新不是单个原子操作)。

相关内容