我在一個 shell 腳本中使用 jq 來操作 JSON 檔案。
我有兩個檔案,我想把它們合并成一個檔案,同時當名稱/值對中的名稱相同時,還可以聚合(求和)這些值。
作為一個例子:
Input1.json
[
{
"A"/span>: "Name 1",
"B": "1.1"。
"C": "2"。
},
{
"A"/span>: "Name 2",
"B": "3.2"。
"C": "4"。
}
]
Input2.json
[
{
"A"/span>: "Name 2",
"B": "5",
"C": "6"。
},
{
"A"/span>: "Name 3",
"B": "7",
"C": "8"。
}
預期結果:
Output.json
[
{
"A"/span>: "Name 1",
"B": "1.1"。
"C": "2"。
},
{
"A"/span>: "Name 2",
"B": "8.2"。
"C": "10"。
},
{
"A"/span>: "Name 3",
"B": "7",
"C": "8"。
}
我可以使用除jq以外的其他工具,但我更希望最終將解決方案包含在一個可以從終端呼叫的shell腳本中。
如果有任何幫助,我們將不勝感激。謝謝你。
uj5u.com熱心網友回復:
您可以使用JSON決議器xidel進行嘗試:我可以使用除
jq之外的其他工具,但我更希望最終將解決方案包含在一個我可以從終端呼叫的shell腳本中。
$ xidel -se '
陣列{
let $src:=(json-doc("Input1.json")(),json-doc("Input2.json")()
for $name in distinct-values($src/A)
讓$obj:=$src[A=$name]
回傳
如果(count($obj) gt 1)那么
map:merge(
$obj[1]() ! {
.如果($obj[1](.)可鑄成小數),那么
string($obj[1](.) $obj[2](.))
否則
$obj[1](.)
}
)
否則
$obj
}
'
uj5u.com熱心網友回復:
這是一種方法,但也有其他的方法:
jq -s '
def to_n: tonumber? // null。
def merge_values($x;$y):
如果$x == $y 那么$x
elif $x == null then $y
elif $y == null then $x
否則($x|to_n)為$xn
| 如果$xn則($y|to_n)為$yn |($xn $yn)|tostring
否則[$x, $y]
結束
結束。
def merge($x;$y):
減少($x $y |keys_unsorted)[] 作為$k (null;
.[$k] = merge_values($x[$k]; $y[$k]) )。
INDEX(.[0][]; .A) as $in1
| INDEX(.[1][]; .A)為$in2
| ($in1 $in2|keys_unsorted)為$keys
| 減少$keys[]為$k ([];
. [merge($in1[$k]; $in2[$k]) ] )
' input1.json inut2.json
uj5u.com熱心網友回復:
對于這樣的問題,jq是非常漂亮的:
$ jq -n '
將inputs[] 減為{$A,$B,$C} ({};
.[$A] |= {
$A,
B: (.B ($B|tonumber))。
C: (.C ($C|tonumber))
}
)
| map({
A,
B: (.B|tostring),
C: (.C|tostring)
})
' input1.json input2.json
第一個reduce創建一個從不同的 "A "值到聚合結果物件的映射。然后給定映射,將其轉換回結果物件的陣列,調整結果的型別。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/309922.html
標籤:
