2016-07-08 49 views
5

İki JSON metin dosyasını değiştirmek istiyorum. Ne yazık ki, rastgele sırayla inşa edilmişler, bu yüzden bende, semantik olarak özdeş olduklarında farklılaşıyorlar. Sadece eleman siparişinden kaynaklanan farklılıkları ortadan kaldırmak için jq (veya herhangi bir şekilde) herhangi bir tam düzende sıralamak istiyorum.Jq kullanarak rasgele JSON'u nasıl tamamen sıralayabilirim?

--sort anahtarları problemin yarısını çözüyor, ancak dizileri sıralamıyor.

Ben jq oldukça bilgisizim ve tüm verileri koruyan bir jq özyinelemeli süzgeç nasıl yazılır bilmiyorum; herhangi bir yardım takdir edilecektir.

Line-by-line 'diff' çıktısının zorunlu olarak iki karmaşık nesneyi karşılaştırmanın en iyi yolu olmadığını anlıyorum, ancak bu durumda iki dosyanın çok benzer olduğunu (neredeyse aynı) ve satır-by- hat farkları benim için iyi.

Using jq or alternative command line tools to diff JSON files çok benzer bir soruyu yanıtlar, ancak farklılıkları yazdırmaz. Ayrıca, sıralı sonuçları kaydetmek istiyorum, bu yüzden gerçekten istediğim JSON sıralamak için sadece bir filtre programı.

+2

Olası yinelenen http://stackoverflow.com/questions/31930041/using-jq-or-alternative-command- satır-araçları-diff-json-dosyaları) –

cevap

5

Burada genel bir işlev olan sıralanmış_araka/1 (bu nedenle aşağıdaki postscript'de açıklanan nedene göre adlandırılır) bir çözüm bulabilirsiniz.

normalize.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 

Örnek kullanılarak deneme:

diff <(jq -S -f normalize.jq FILE1) <(jq -S -f normalize.jq FILE2) 

Dipnot: bu yanıt yayınlanan ilk sonra walk/1 arasında yerleşik tanımı revize edilmiştir: Şimdi keys_unsorted kullanır keys'dan ziyade.

+0

Sadece ihtiyacım olan şey, teşekkürler! Gördüğünüz gibi, bu çözümün ilgili gönderisinde bir varyasyonunu yayınladığınızı görüyorum, ancak daha basit bir örnek burada bir takım soruları yanıtladı. –

3

İki JSON metin dosyası ayırt etmek istiyorum.

-set seçeneğiyle kullanın jd: Hayır çıkış fark anlamına

.

Farklılıklar bir @ yol ve + veya - olarak gösterilir.

$ jd -set A.json C.json 

@ ["People",{}] 
+ "Carla" 

çıkış diffs da -p seçeneği ile yama dosyaları olarak kullanılabilir.

$ jd -set -o patch A.json C.json; jd -set -p patch B.json 

{"City":"Boston","People":["John","Carla","Bryan"],"State":"MA"} 

https://github.com/josephburnett/jd#command-line-usage

([fark JSON dosyalarına jQ veya alternatif komut satırı araçlarını kullanma] arasında