создание "таблицы" из json с использованием jq - PullRequest
0 голосов
/ 03 августа 2020

Возвращение одного из моих примеров данных из предыдущего вопроса:

{
  "countries": [
    {
      "countryName": "CZ",
      "cities": [
        {
          "cityName": "Prague",
          "streets": [
            {
              "streetName": "Norská"
            },
            {
              "streetName": "Slovenská"
            }
          ]
        }
      ]
    },
    {
      "countryName": "FR",
      "cities": [
        {
          "cityName": "Paris",
          "streets": [
            {
              "streetName": "rue piat"
            },
            {
              "streetName": "rue lesage"
            }
          ]
        }
      ]
    }
  ]
}

Я хотел бы использовать jq для создания таблицы с открытым текстом / asciidoc / markdown из этих данных, но мне не хватает некоторых базовых c идея, как это сделать. Я не получаю дублирования в данном столбце.

Итак, ожидаемый результат может выглядеть так:

CZ Prague Norská
CZ Prague Slovenská
FR Paris rue piat
FR Paris rue lesage

ie. как выполнить итерацию по массиву верхнего уровня countries, выбрать из него поле countryName и перебрать поле cities, содержащееся в элементах массива countries, и выбрать cityName из него, et c. чтобы получить результирующий массив триплетов, который затем может быть преобразован в желаемый выходной текст.

EDIT:

  • обновлено json для синхронизации c с ожидаемым выходные данные.

  • тем временем мне повезло с выражением:

    jq '.countries [] | .countryName как $ country | .cities [] | .cityName как $ city | .streets [] | $ country + "" + $ city + "" + .streetName '

, но использование @csv по какой-то причине не помогло мне.

jq '[(.countries[] | .countryName as $country| .cities[] | .cityName as $city | .streets[] | [$country,$city,.streetName])] | @csv' < /tmp/sampleData.json

Я был бы признателен за любые предложения по улучшению.

EDIT2: для работы @csv он должен быть загружен с массивом (который есть), но не массивом массивов . Заблуждение об императивном стиле программирования. В любом случае это правильный:

jq '[(.countries[] | .countryName as $country| .cities[] | .cityName as $city | .streets[] | [$country,$city,.streetName])] | .[] | @csv' < /tmp/sampleData.json 

1 Ответ

2 голосов
/ 03 августа 2020

Ваше решение jq можно немного упростить, что также повысит его эффективность:

.countries[]
| .countryName as $country
| .cities[]
| .cityName as $city
| .streets[]
| [$country, $city, .streetName]
| @csv

В сочетании с параметрами командной строки -r это, конечно, создаст действительный CSV, но ваш Q указывает на предпочтение удаления (ненужных?) кавычек. В случае показанных примеров данных вы можете обойтись заменой @csv на join(","), но в целом необходимо следить за запятыми и другими символами, которые являются специальными для CSV.

Общий случай

Следующее, похоже, обрабатывает общий случай, но полагается на sed для обработки соглашений CSV относительно кавычек и встроенных символов новой строки и не было тщательно протестировано:

< sampleData.json jq -r '
def q:
  if type == "string" and test("[,\n\"]")
  then tojson 
  else . end;
  
.countries[]
| .countryName as $country
| .cities[]
| .cityName as $city
| .streets[]
| [$country, $city, .streetName]
| map(q)
| join(",")
' | sed -e 's/\\\"/""/g' -e 's/\\n/\
/g'

...