2015-11-23 4 views

cevap

5

jq -s . *.json > output.json "argüman listesi çok uzun" üretir; Eğer fix it using zargs in zsh olabilir:

$ find -maxdepth 1 -name \*.json -exec cat {} + | jq -s . > output.json 

"Data in jq is represented as streams of JSON values ... This is a cat-friendly format - you can just join two JSON streams together and get a valid JSON stream.": @chepner's answer gösterildiği gibi

$ zargs *.json -- cat | jq -s . > output.json 

Eğer find kullanarak taklit olamayacağını

bunu yapabilirim bana belli değil
$ echo '{"a":1}{"b":2}' | jq -s . 
[ 
    { 
    "a": 1 
    }, 
    { 
    "b": 2 
    } 
] 
2

[kullanmaya EDITED bulmak]

seferinde bir dosyayı işlemek olacaktır dikkate almak ve sonra "slurp" onları Bir şey açık:

$ while read f ; cat "$f" ; done <(find . -maxdepth 1 -name "*.json") | jq -s . 

Ancak bu muhtemelen bir çok gerektirecektir hafızanın Böylece şu neye ihtiyacınız daha yakın olabilir:

#!/bin/bash 
# "slurp" a bunch of files 
# Requires a version of jq with 'inputs'. 
echo "[" 
while read f 
do 
    jq -nr 'inputs | (., ",")' $f 
done < <(find . -maxdepth 1 -name "*.json") | sed '$d' 
echo "]" 
+0

ki afaik çünkü Yaptığım şey, bir grup jöle nesnesini {...} 'çekmek ve onları iyi oluşturulmuş bir dizi nesneye yerleştirmekti. [{...}, {...}, {...}] '. Bu, önerdiğiniz şeyle hala devam ediyor mu? – Kristian

+1

[Bunun gibi ls' kullanmayın] (http://mywiki.wooledge.org/ParsingLs). Bunun yerine 'for' döngüsünü kullanabilirsiniz: * .json'da f için; kedi "$ f" yapmak; tamamlandı | jq -s '.' (Aslında, 'ls * .json 'orijinalinin yaptığı aynı nedenden dolayı başarısız olur: pathname genişlemesinden kaynaklanan çok fazla komut satırı argümanı.) – chepner

+0

Bu türden' find 'özelliğini kullanmamanızı tavsiye ederim. JSON dosyalarından birinin adında yeni bir satır varsa, yalnızca gerçekten sorun oluşturur.Diğer bazı dosya adları sorunlu olabilir, ancak bunun yerine 'IFS = read -r f' kullanılarak ele alınabilir. – chepner

1

sorun bir komut satırının uzunluğu sınırlı olması ve *.json tek bir komut satırı için çok fazla argüman üretir.

for f in *.json; do 
    cat "$f" 
done | jq -s '.' > output.json 
: Tek geçici çözüm bash sonucun üzerinde yineleme, çünkü bir komut satırı ile aynı sınırları olmayan bir for döngü içinde desen genişletmek içten ziyade harici komut için bir argüman listesi oluşturmak zorunda olduğunu

Bu, her dosya için bir kez cat çalıştırmayı gerektirdiğinden, oldukça verimsizdir. Daha verimli bir çözüm, cat numaralı telefonu arayarak her seferinde olabildiğince çok dosya ile find'u kullanmaktır.

find . -name '*.json' -exec cat '{}' + | jq -s '.' > output.json 

(Sadece yanı

find . -name '*.json' -exec jq -s '{}' + > output.json 

kullanmak mümkün olabilir; tek bir çağrı kıyaslanamaz hangi dosya olduğunu ve nasıl birden çok çağrı jq için -s seçeneğini kullanarak bağlı olabilir.

+0

Maalesef, bu, "-s" jq seçeneğinin istenen davranışını çoğaltmaz. ("Slurp" seçeneği, JSON öğelerinin * akışından * bir JSON dizisi oluşturur.) – peak

+0

Muhtemelen bu son 'bul 'komutunun sonucunu' jq '(' jq') 'nin uygun bir çağrısına borulamak suretiyle bunu düzeltebilirsiniz. [] | [.] ''?), ama muhtemelen doğru olma çabalarına değmez. – chepner