it-source

셸 스크립트에서 JSON 데이터 읽기

criticalcode 2023. 3. 2. 22:18
반응형

셸 스크립트에서 JSON 데이터 읽기

셸에서는 다음 형식의 JSON 응답을 읽어야 합니다.

 { "Messages": [ { "Body": "172.16.1.42|/home/480/1234/5-12-2013/1234.toSort", "ReceiptHandle": "uUk89DYFzt1VAHtMW2iz0VSiDcGHY+H6WtTgcTSgBiFbpFUg5lythf+wQdWluzCoBziie8BiS2GFQVoRjQQfOx3R5jUASxDz7SmoCI5bNPJkWqU8ola+OYBIYNuCP1fYweKl1BOFUF+o2g7xLSIEkrdvLDAhYvHzfPb4QNgOSuN1JGG1GcZehvW3Q/9jq3vjYVIFz3Ho7blCUuWYhGFrpsBn5HWoRYE5VF5Bxc/zO6dPT0n4wRAd3hUEqF3WWeTMlWyTJp1KoMyX7Z8IXH4hKURGjdBQ0PwlSDF2cBYkBUA=", "MD5OfBody": "53e90dc3fa8afa3452c671080569642e", "MessageId": "e93e9238-f9f8-4bf4-bf5b-9a0cae8a0ebc" } ] }

여기서는 "Body"의 재산 가치에만 관심이 있습니다.나는 다음과 같은 몇 가지 실패한 시도를 했다.

 jsawk -a 'return this.Body' 

또는

 awk -v k="Body" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]} 

그러나 그것은 충분하지 않았다.누가 나 좀 도와줄래?

있어jq명령줄에서 json을 해석하는 경우:

 jq '.Body'

jq에 대해서는, https://stedolan.github.io/jq/ 를 참조해 주세요.

dr;dr

$ cat /tmp/so.json | underscore select '.Messages .Body' 
["172.16.1.42|/home/480/1234/5-12-2013/1234.toSort"]

Javascript CLI 도구

다음과 같은 Javascript CLI 도구를 사용할 수 있습니다.

모두 선택name의 아이들addons:

underscore select ".addons > .name"

underscore-clijson:select() 문서뿐만 아니라 다른 실제 예도 제공합니다.

마찬가지로 Bash regexp를 사용합니다.키/값 쌍을 가로챌 수 있어야 합니다.

key="Body"
re="\"($key)\": \"([^\"]*)\""

while read -r l; do
    if [[ $l =~ $re ]]; then
        name="${BASH_REMATCH[1]}"
        value="${BASH_REMATCH[2]}"
        echo "$name=$value"
    else
        echo "No match"
    fi
done

정규 표현은 여러 공백/탭 또는 줄바꿈과 일치하도록 조정할 수 있습니다.값이 내장되어 있으면 동작하지 않는다"이것은 일러스트입니다.「산업용」파서를 사용하는 것이 좋습니다.

대략적인 방법은 다음과 같습니다: JSON을bash에 대한 변수.eval그들.

이것은 다음 경우에만 유효합니다.

  • 네스트된 어레이를 포함하지 않는 JSON 및
  • 신뢰할 수 있는 소스로부터의 JSON (단, 셸 스크립트를 혼란스럽게 하거나 시스템을 해칠 가능성이 있습니다)경고를 받았습니다.

네, CPAN 덕분에 이 작업을 수행하기 위해 PERL을 사용하지만 스크립트에 직접 포함할 수 있을 정도로 작기 때문에 빠르고 쉽게 디버깅할 수 있습니다.

json2bash() {
perl -MJSON -0777 -n -E 'sub J {
my ($p,$v) = @_; my $r = ref $v;
if ($r eq "HASH") { J("${p}_$_", $v->{$_}) for keys %$v; }
elsif ($r eq "ARRAY") { $n = 0; J("$p"."[".$n++."]", $_) foreach @$v; }
else { $v =~ '"s/'/'\\\\''/g"'; $p =~ s/^([^[]*)\[([0-9]*)\](.+)$/$1$3\[$2\]/;
$p =~ tr/-/_/; $p =~ tr/A-Za-z0-9_[]//cd; say "$p='\''$v'\'';"; }
}; J("json", decode_json($_));'
}

처럼 사용하다eval "$(json2bash <<<'{"a":["b","c"]}')"

하지만 심하게 테스트 되진 않았어요업데이트, 경고 및 기타 예는 GIST를 참조하십시오.

갱신하다

(유감스럽게도 C코드가 너무 길어서 여기서 복제할 수 없기 때문에 링크 전용 솔루션을 다음에 제시하겠습니다).

위의 솔루션을 좋아하지 않는 모든 사용자에게는 (안전하게) JSON을 셸 변수로 변환하는 C프로그램 json2sh가 있습니다.와는 대조적으로perl스니펫은 JSON이 잘 형성되어 있는 한 어떤 JSON도 처리할 수 있습니다.

경고:

  • json2sh많이 테스트되지 않았습니다.
  • json2shshellshock 패턴으로 시작하는 변수를 생성할 수 있습니다.() {

나는 썼다json2sh후처리할 수 있다.bson셸 포함:

bson2json()
{
printf '[';
{ bsondump "$1"; echo "\"END$?\""; } | sed '/^{/s/$/,/';
echo ']';
};

bsons2json()
{
printf '{';
c='';
for a;
do
  printf '%s"%q":' "$c" "$a";
  c=',';
  bson2json "$a";
done;
echo '}';
};

bsons2json */*.bson | json2sh | ..

설명:

  • bson2json.bsonJSON을 사용하다
    • 것이 정상적으로는, 「」가 됩니다.END0 그렇지 않으면 -마커가 적용되어 .그렇지 않으면 다음과 같은 것이 표시됩니다.END1.
    • END 않으면 비어있습니다. -마커가 필요합니다.마커가 없으면 비어 있습니다..bson파일이 표시되지 않습니다.
  • bsons2json을 내던지다.bson은 「」, 「」입니다.bson2json는 파일명으로 인덱싱됩니다.

후, 이것은 그,, 것것에 this this this this this 、 this 、 this 、 this 、 this this this 。json2sh 쓸 수 grep/source/evaletc. 값을 위해 사용합니다./etc.

이렇게 하면 먼저 MongoDB로 Import할 필요 없이 쉘 수준에서 MongoDB 덤프의 내용을 빠르게 처리할 수 있습니다.

언급URL : https://stackoverflow.com/questions/20488315/read-json-data-in-a-shell-script

반응형