我有一个 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
计数器的获取和更新不是单个原子操作)。