programing

bash 스크립트로 json 파일 변경

kakaobank 2023. 3. 18. 08:46
반응형

bash 스크립트로 json 파일 변경

다음 문제를 해결하기 위해 당신의 도움이 필요합니다.다음과 같은 JSON 파일이 있습니다.

{
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
}

새로운 키를 추가 및 삭제하는 방법(예:"key4": "value4"bash 스크립트로?새로운 키를 추가 또는 삭제하기 전에 파일의 마지막 키 끝에 쉼표를 추가 또는 삭제해야 하는 문제도 있습니다.

감사해요.

다음과 같은 JSON CLI 를 사용하는 것이 가장 좋습니다.

  • Ubuntu와 같은 Debian 기반 시스템에서는 다음을 통해 설치할 수 있습니다.sudo apt-get install jq
  • MacOS에서는 Homebrew(http://brew.sh/)가 설치되어 있는 경우brew install jq

예를 들어, 다음 입력 문자열에 따라 출력은stdout:

jsonStr='{ "key1": "value1", "key2": "value2", "key3": "value3" }'

"key3" 제거:

jq 'del(.key3)' <<<"$jsonStr"

값이 "value4"인 속성 "key4" 추가:

jq '. + { "key4": "value4" }' <<<"$jsonStr"

기존 속성 "key1" 값을 "new-value1"로 변경합니다.

jq '.key1 = "new-value1"' <<<"$jsonStr"

보다 견고한 대안:
새로운 값을 전달하면--arg,jq는, 다음의 값을 적절히 이스케이프 합니다.

jq '.key1 = $newVal' --arg newVal '3 " of rain' <<<"$jsonStr"

key3」를 삭제하는 예를 사용하고, JSON 파일을 인스톨(개념상)하는 경우는, 다음의 순서에 따릅니다.

# Create test file.
echo '{ "key1": "value1", "key2": "value2", "key3": "value3" }' > test.json

# Remove "key3" and write results back to test.json (recreate it with result).
jq -c 'del(.key3)' test.json > tmp.$$.json && mv tmp.$$.json test.json

입력 파일을 직접 교체할 수 없으므로 결과는 입력 파일을 대체하는 임시 파일에 기록됩니다.

주의:-c이 옵션을 사용하면 예쁜 프린트가 아닌 콤팩트한 JSON을 만들 수 있습니다.

모든 옵션 및 명령어에 대해서는http://http://stedolan.github.io/jq/manual/ 의 메뉴얼을 참조해 주세요.

모든 사람에게 정답은 아니지만 시스템에 NodeJs가 이미 설치되어 있다면 이를 사용하여 JSON을 쉽게 조작할 수 있습니다.

예:

#!/usr/bin/env bash
jsonFile=$1;

node > out_${jsonFile} <<EOF
//Read data
var data = require('./${jsonFile}');

//Manipulate data
delete data.key3
data.key4 = 'new value!';

//Output data
console.log(JSON.stringify(data));

EOF

JSON 조작만 하면 노드(즉, 다른 bash 기능은 실제로 필요하지 않습니다)가 있는 경우 노드를 인터프리터로 사용하여 스크립트를 직접 작성할 수 있습니다.

#! /usr/bin/env node
var data = require('./'+ process.argv[2]);
/*manipulate*/
console.log(JSON.stringify(data));

Lenny의 답변을 바탕으로 노드의 -p 옵션을 사용할 수 있습니다.이 옵션은 주어진 스크립트를 평가하고 출력을 다음 위치에 씁니다.stdout.

쉽게 수정할 수 있도록 확산 연산자를 사용하면 다음과 같은 이점이 있습니다.

node -p "JSON.stringify({...require('./data.json'), key4: 'value4'}, null, 2)" > data.json

파일을 변경하려면 sponge 명령을 사용합니다.

echo '{ "k": "old value" }' >f.json

cat f.json | jq '.k = $v' --arg v 'new value' | sponge f.json

참고 항목: jq 문제 파일 편집 #105

jq 대체: jaq

echo '{ "k": "old value" }' >f.json

jaq -i '.k = $v' --arg v 'new value' f.json

...그렇지만jaq보다 기능이 적다jq

다음은 "comma issue"를 포함한 완전한 bash의 예입니다.

#!/bin/bash
# This bash script just uses the sed command to 
#   replace/insert a new key at/before/after an 
#   existing key in a json file 
# The comma issue:
# - replace: with/without, as previous entry
# - before: always add
# - after: add before, if there was none
SED_CMD="/tmp/sed_cmd.tmp"
JSFILE1="./data1.json"
JSFILE2="./data2.json"
JSFILE3="./data3.json"
SEARCH_KEY="key3"
# create json input file
echo -e '{\n\t"key1": "value1",\n\t"key2": "value2",\n\t"key3": "value3"\n}' > $JSFILE1
echo -e "input:"
cat $JSFILE1
# duplicate twice
cp $JSFILE1 $JSFILE2 && cp $JSFILE1 $JSFILE3
# find the SEARCH_KEY and store the complete line to SEARCH_LINE 
SEARCH_LINE=`cat data.json | grep $SEARCH_KEY`
echo "SEARCH_LINE=>$SEARCH_LINE<"
# replace SEARCH_LINE
IS_COMMA=`echo $SEARCH_LINE | grep ","`
[ -z "$IS_COMMA" ] && \
    echo "s+$SEARCH_LINE+\t\"keyNew\": \"New\"+g" > $SED_CMD || \
    echo "s+$SEARCH_LINE+\t\"keyNew\": \"New\",+g" > $SED_CMD
sed -i -f $SED_CMD $JSFILE1
echo -e "replace:"
cat $JSFILE1
# insert before SEARCH_LINE
echo "s+$SEARCH_LINE+\t\"keyNew\": \"New\",\n$SEARCH_LINE+g" > $SED_CMD
sed -i -f $SED_CMD $JSFILE2
echo -e "before:"
cat $JSFILE2
# insert after SEARCH_LINE
IS_COMMA=`echo $SEARCH_LINE | grep ","`
[ -z "$IS_COMMA" ] && \
    echo "s+$SEARCH_LINE+$SEARCH_LINE,\n\t\"keyNew\": \"New\"+g" > $SED_CMD || \
    echo "s+$SEARCH_LINE+$SEARCH_LINE\n\t\"keyNew\": \"New\",+g" > $SED_CMD
sed -i -f $SED_CMD $JSFILE3
echo -e "after:"
cat $JSFILE3
exit 0

새로운 키를 추가 및 삭제하는 방법(예:"key4": "value4"bash 스크립트로?

과 같은 전용 JSON 툴을 사용하는 것은 순수한 Bash 기능을 사용하는 것보다 더 좋은 방법입니다.

새 특성-값 쌍 추가

xidel -s '{"a":1,"b":2,"c":3}' -e '($json).d:=4'                 # dot notation
xidel -s '{"a":1,"b":2,"c":3}' -e '{|$json,{"d":4}|}'            # JSONiq (deprecated)
xidel -s '{"a":1,"b":2,"c":3}' -e 'map:put($json,"d",4)'         # XQuery
xidel -s '{"a":1,"b":2,"c":3}' -e 'map:merge(($json,{"d":4}))'   # XQuery
{
  "a": 1,
  "b": 2,
  "c": 3,
  "d": 4
}

쌍을 합니다."c":3

xidel -s '{"a":1,"b":2,"c":3}' --xmlns:jnlib="http://jsoniq.org/function-library" -e 'jnlib:remove-keys($json,"c")'   # JSONiq (deprecated)
xidel -s '{"a":1,"b":2,"c":3}' -e 'map:remove($json,"c")'   # XQuery
{
  "a": 1,
  "b": 2
}

값경의 "c" 4

xidel -s '{"a":1,"b":2,"c":3}' -e '($json).c:=4'
xidel -s '{"a":1,"b":2,"c":3}' -e 'map:put($json,"c",4)'
xidel -s '{"a":1,"b":2,"c":3}' -e 'map:merge(($json,{"c":4}),{"duplicates":"use-last"})'
{
  "a": 1,
  "b": 2,
  "c": 4
}

언급URL : https://stackoverflow.com/questions/24942875/change-json-file-by-bash-script

반응형