Как я могу полностью отсортировать произвольный JSON с помощью jq?
Я хочу различать два текстовых файла JSON. К сожалению, они построены в произвольном порядке, поэтому я получаю различия, когда они семантически идентичны. Я хотел бы использовать jq (или что-то еще) для сортировки их в любом полном порядке, чтобы устранить различия только из-за упорядочения элементов.
--sort-keys решает половину проблемы, но не сортирует массивы.
Я довольно незнаком с jq и не знаю, как написать рекурсивный фильтр jq, который сохраняет все данные; любая помощь будьте благодарны.
Я понимаю, что линейный вывод "diff" не обязательно является лучшим способом сравнения двух сложных объектов, но в этом случае я знаю, что два файла очень похожи (почти идентичны), и линейные различия хороши для моих целей.
использование jq или альтернативных инструментов командной строки для различения файлов json отвечает на очень похожий вопрос, но не печатает различия. Кроме того, я хочу сохранить отсортированные результаты, поэтому я действительно хочу программа фильтрации для сортировки JSON.
2 ответов
вот решение, использующее общую функцию sorted_walk/1 (названы так по причине, описанной в постскриптуме ниже).
нормализовать.jq не:
# Apply f to composite entities recursively using keys[], and to atoms
def sorted_walk(f):
. as $in
| if type == "object" then
reduce keys[] as $key
( {}; . + { ($key): ($in[$key] | sorted_walk(f)) } ) | f
elif type == "array" then map( sorted_walk(f) ) | f
else f
end;
def normalize: sorted_walk(if type == "array" then sort else . end);
normalize
пример использования bash:
diff <(jq -S -f normalize.jq FILE1) <(jq -S -f normalize.jq FILE2)
POSTSCRIPT: встроенное определение walk/1
был пересмотрен после того, как этот ответ был впервые опубликован: теперь он использует keys_unsorted
, а не keys
.
Я хочу различать два текстовых файла JSON.
использовать jd
С :
отсутствие выхода означает отсутствие разницы.
$ jd -set A.json B.json
различия отображаются в виде @ path и + или -.
$ jd -set A.json C.json
@ ["People",{}]
+ "Carla"
дифференциалы выход может быть использован как файлы патч с .
$ jd -set -o patch A.json C.json; jd -set -p patch B.json
{"City":"Boston","People":["John","Carla","Bryan"],"State":"MA"}