Преобразовать огромный старый формат json в новый формат json с помощью каких-то команд Linux?

Используйте

find path/to/dir -name "*.ext1" -o -name "*.ext2"

Пояснение

  1. Первый параметр — это каталог, в котором вы хотите выполнить поиск.
  2. По умолчанию findвыполняет рекурсию.
  3. -oозначает -or. Итак, выше означает поиск этого подстановочного знака ИЛИ этого. Если у вас есть только один паттерн, то -oне нужен.
  4. Подстановочный знак необходимо заключать в кавычки.
1
05.10.2020, 18:27
2 ответа

Обработку JSON лучше всего выполнять с помощью инструмента, который понимает JSON, например jqили Python. Вот скрипт Python, который делает то, что вам нужно:

#! /usr/bin/env python3

import json
import sys
from collections import defaultdict


def combine(data, key, id_key):
    new_settings = defaultdict(list)
    for setting in data[key]:
        # Remove the ID from the setting and add it to the list of settings for that ID
        new_settings[setting.pop(id_key)].append(setting)
    # arrange the new settings in the desired format and overwrite the old settings
    data[key] = [{id_key: key, "entries": values} for key, values in new_settings.items()]


data = json.load(sys.stdin)
combine(data, "clientSettings", "clientId")
combine(data, "productSettings", "productId")
print(json.dumps(data))

Подайте JSON на стандартный ввод и используйте вывод:

$./process.py < old.json | jq
{
  "clientSettings": [
    {
      "clientId": 12345,
      "entries": [
        {
          "key": "abc",
          "value": false
        },
        {
          "key": "def",
          "value": false
        },
        {
          "key": "ghi",
          "value": false
        }
      ]
    },
    {
      "clientId": 9876,
      "entries": [
        {
          "key": "lkmn",
          "value": false
        }
      ]
    }
  ],
  "productSettings": [
    {
      "productId": 11,
      "entries": [
        {
          "key": "jkl",
          "value": true
        },
        {
          "key": "mno",
          "value": true
        }
      ]
    },
    {
      "productId": 12,
      "entries": [
        {
          "key": "jkl",
          "value": true
        },
        {
          "key": "mno",
          "value": true
        }
      ]
    }
  ],
  "customerSettings": [
    {
      "key": "enableData",
      "value": false
    },
    {
      "key": "minPriceValue",
      "value": "1.0"
    },
    {
      "key": "presentData",
      "value": "AEGIS"
    }
  ],
  "thothTest": {
    "9876": [
      "K"
    ],
    "5431": [
      "A",
      "L"
    ],
    "5123": [
      "L"
    ]
  },
  "osirisTest": {
    "7678": [
      "K"
    ]
  }
}
1
18.03.2021, 22:59

Вы можете изменить формат JSON с помощью jqразными способами. Один из способов — сгруппировать по .clientIdи сопоставить с новым объектом, где .clientIdбудет вне сгруппированного массива. Использование group_byиmap:

jq '.clientSettings |=
    ( group_by(.clientId) |
      map( {clientId:.[0].clientId, entries: del(.[].clientId)} )
    ) |
    .productSettings |=
    ( group_by(.productId) |
      map( {productId:.[0].productId, entries: del(.[].productId)} )
    ) ' file.json

Я только что скопировал -ту же команду для второго объекта.


Если вам нужно часто выполнять операции с большими JSON, я предлагаю вам ознакомиться и использовать mongodb или любую аналогичную базу данных документов, например, см. эту карту -страницу сокращения из руководства, это то, что вы делаете сейчас, без части сокращения. Все эти операции могут быть быстрее, чем разбор json-файла, синтаксис аналогичен простому javascript.

2
18.03.2021, 22:59

Теги

Похожие вопросы