Анализируйте JSON и перебирайте объекты с помощью jq - PullRequest
0 голосов
/ 17 июня 2020
[ 
{ "id":"1", 
  "metadata":{"version":"1.0","author":"user1"}
},
{ "id":"2", 
  "metadata":{"version":"1.0","author":"user2","timestamp":"2019-02-05"}
},
{ "id":"3", 
  "metadata":{"version":"1.0","author":"user3","price":"10.0"}
}]

Я пытаюсь проанализировать вышеуказанный json (data1. json) с помощью jq, но мне не удается получить доступ к объекту метаданных. В конечном итоге я буду использовать объект метаданных для вставки в базу данных в виде строки. Может иметь любое количество полей, структура не фиксированная. Это сценарий, который я использую.

#!/usr/bin/env bash
id=($(jq '.[] | .id' data1.json | tr -d '"'))
metadata=($(jq '.[] | .metadata' data1.json))

n_id=${#id[@]}
n_meta=${#metadata[@]}

echo $n_id 
echo $n_meta 

for (( i=0; i<n_id; i++ )); do
    echo ${metadata[$i]} 
done

Ожидаемый результат:

{"version":"1.0","author":"user1"}

{"version":"1.0","author":"user2","timestamp":"2019-02-05"}

{"version":"1.0","author":"user3","price":"10.0"}

Что я здесь делаю не так? Любая помощь приветствуется.

Ответы [ 3 ]

1 голос
/ 17 июня 2020

Вы можете сделать это, используя jt c:

Если вышеуказанное содержимое находится в файле foo.json, вы можете сделать:

% <foo.json jtc -tc -w '<metadata>l:'
{ "author": "user1", "version": "1.0" }
{ "author": "user2", "timestamp": "2019-02-05", "version": "1.0" }
{ "author": "user3", "price": "10.0", "version": "1.0" }

-tc означает «компактный формат вывода»

-w .. - это путь перехода

<metadata> соответствие метаданных, l означает соответствие метки, : означает «все '

1 голос
/ 17 июня 2020

Все объекты метаданных, по одному на строку, не заключенные в массив?

$ jq -c '.[] | .metadata' data1.json
{"version":"1.0","author":"user1"}
{"version":"1.0","author":"user2","timestamp":"2019-02-05"}
{"version":"1.0","author":"user3","price":"10.0"}

Но вы уже делаете это для своего metadata массива в коде оболочки. Если вы хотите распечатать этот массив по одному в строке:

printf "%s\n" "${metadata[@]}"

Чтобы строки, напечатанные с помощью jq в массиве, когда в содержимом объекта есть пробелы:

mapfile -t metadata < <(jq -c '.[] | .metadata' data1.json)

или

while IFS= read -r obj; do metadata+=("$obj"); done < <(jq -c '.[] | .metadata' data1.json)
0 голосов
/ 17 июня 2020

Почему бы просто не отфильтровать ваши данные с помощью самого jq?

jq -c '.[] | .metadata' data1.json

См. Ответ Шона, поскольку я не учел другие данные.

...