アイテムリストのIDを含むjsonファイルがあります。
[
{
"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
100未満の値を持つトップレベルの匿名配列のentries
最初の要素を取得するには、次のようにします。
jq 'map(select(.entries < 100)) | first.list_id' file
(これは整数list_id
値を返します。)
entries
値を1ずつ増やすには
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
(これらの文書は更新された文書を返します。)
したがって、シェルスクリプトで次のようにします。
# 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
カウンタが0から始まると仮定)。
[
{ "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" }
]
値が0以外の場合、上記のシェルスクリプトは対応する()オプションをlist_id
使用して短縮できます。jq
-e
--exit-status
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
カウンタのインポートと更新が単一のアトミック操作ではないため)。 。