Json의 값을 x번 변수로 사용

Json의 값을 x번 변수로 사용

항목 목록의 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_id100보다 작은 값을 가진 최상위 익명 배열의 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카운터 가져오기 및 업데이트가 단일 원자성 작업이 아니기 때문입니다). .

관련 정보