Сортировка файла JSON по имени внешнего объекта

У меня есть файл json input.json таким образом:

{
   "foo":{
       "prefix":"abc",
       "body":[1,2,3]
   },
   "bar":{
       "prefix":"def",
       "body":[4,5,6]    
   }
}

Я хотел бы отсортировать его по именам внешних объектов, где "bar" стоит перед "foo" в алфавитном порядке, например:

{
   "bar":{
       "prefix":"def",
       "body":[4,5,6]    
   },
   "foo":{
       "prefix":"abc",
       "body":[1,2,3]
   }
}

для создания файла output.json.

Версии этого вопроса были заданы для Java/Javascript (здесь и здесь)

Есть ли способ сделать это с помощью инструмента командной строки, такого как sed/awk или boost.json?

Объекты в JS/JSON представляют собой неупорядоченные наборы пар ключ-значение, порядок свойств не имеет внутреннего значения. Почему для вас важен порядок?

knittl 14.02.2023 17:30

@knittl (Как всегда, все довольно сложно.) У меня есть фрагменты VSCode в виде файлов json, где ключевые слова триггера — это имена самых внешних объектов в этом файле. Фрагменты кода Visual Studio IDE не являются файлами json. Они хранятся в другом формате, а сами ключевые слова триггера являются именами файлов, что позволяет сортировать их по имени файла в проводнике Windows. Я пытаюсь сопоставить два набора фрагментов. Я не уверен, что есть другой способ сделать это, кроме как отсортировать файл json.

Tryer 14.02.2023 17:35
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
1
2
65
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Используя jq, вы можете использовать встроенный keys, чтобы получить имена ключей в отсортированном порядке и сформировать соответствующий объект значения.

jq 'keys[] as $k | { ($k) : .[$k] }' json

Обратите внимание, что у jq есть опция поля --sort-keys, которую здесь нельзя использовать, поскольку она также внутренне сортирует объекты внутреннего уровня.

Это работает для меня. ТЫ! Вывод печатает 4, 5, 6 и т. д. в отдельных строках. Есть ли способ сделать вывод точно соответствующим входному файлу (с точки зрения общего количества строк в файлах) с заменой только определенных строк текста?

Tryer 14.02.2023 17:43

@Tryer jq выполняет форматирование ввода JSON по умолчанию, что, к сожалению, не позволяет контролировать определенные поля.

Inian 14.02.2023 17:48

переформатирование: см., например, stackoverflow.com/questions/75428312/…

peak 14.02.2023 18:17

Чтобы получить желаемый результат, как указано в вопросе, вам придется адаптировать этот подход следующим образом: [keys[] as $k | {($k): .[$k]} ] | add

peak 15.02.2023 03:23

@peak да, действительно. Мне пришлось изменить предложенный ответ на основе вашей поправки, чтобы получить именно тот результат, который я хотел в OP. Ваш метод тоже отлично работает. Хоуп Иниан исправляет свой ответ.

Tryer 15.02.2023 05:44

Вот решение jq без переменных:

to_entries | sort_by(.key) | from_entries

Также стоит отметить, что gojq, реализация jq на Go, в настоящее время всегда сортирует ключи во всех объектах JSON.

Просто чтобы убедиться, что я понимаю ваш ответ - должно ли это быть jq to_entries..., а не просто to_entries...? Мне пришлось установить jq на мою машину. В вашем ответе непонятно, сама ли это утилита jq или какая-то другая утилита.

Tryer 15.02.2023 02:55

@Tryer Да, это jq 'to_entries | sort_by(.key) | from_entries' input.json

pmf 15.02.2023 09:40

Другие вопросы по теме