因此我的目录中有三个.json文件。我已经动态创建了第一个文件(使用linux bash和jq),其中包含一个对象,包括数组“RATIO”:
ratio.json:
[
{...,"RATIO":[0.5,0.7,0.8,0.9], ....}
]
在第二个文件中我存储了常量(这只是硬编码所以常量也可以直接移动到代码中,如果这更容易):
constants.json:
[
{"ID":"aaa","CONST":250},
{"ID":"bbb","CONST":350},
{"ID":"ccc","CONST":200},
{"ID":"ddd","CONST":190}
]
第三个文件是应该发生“神奇”的地方:
data.json:
[
{"ID":"aaa","time_CET":"00:00:00"},
{"ID":"aaa","time_CET":"00:15:00"},
{"ID":"aaa","time_CET":"00:30:00"},
{"ID":"aaa","time_CET":"00:45:00"},
{"ID":"bbb","time_CET":"00:00:00"},
{"ID":"bbb","time_CET":"00:15:00"},
{"ID":"bbb","time_CET":"00:30:00"},
{"ID":"bbb","time_CET":"00:45:00"},
{"ID":"ccc","time_CET":"00:00:00"},
{"ID":"ccc","time_CET":"00:15:00"},
{"ID":"ccc","time_CET":"00:30:00"},
{"ID":"ccc","time_CET":"00:45:00"},
{"ID":"ddd","time_CET":"00:00:00"},
{"ID":"ddd","time_CET":"00:15:00"},
{"ID":"ddd","time_CET":"00:30:00"},
{"ID":"ddd","time_CET":"00:45:00"}
]
此数组中的所有对象都应该通过元素“VAL”进行扩展,该元素是通过将RATIO与CONST相乘来计算的。所以在我的情况下,RATIO [0](即0.5)用于time_CET =“00:00:00”的每个对象。 RATIO [1]用于time_CET = 00:15:00等,依此类推。 data.json中的数组已经按照您所看到的排序(00:00:00总是每个ID的第一个),这就是为什么我认为数组索引的技巧应该有效。 所以最后,data.json文件看起来应该是这样的(右边是VAL的计算逻辑):
data.json:
[
{"ID":"aaa","time_CET":"00:00:00", "VAL": 125}, ->0.5*250
{"ID":"aaa","time_CET":"00:15:00", "VAL": 175}, ->0.7*250
{"ID":"aaa","time_CET":"00:30:00", "VAL": 200}, ->0.8*250
{"ID":"aaa","time_CET":"00:45:00", "VAL": 225}, ->0.9*250
{"ID":"bbb","time_CET":"00:00:00", "VAL": 175}, ->0.5*350
{"ID":"bbb","time_CET":"00:15:00", "VAL": 245}, ->0.7*350
{"ID":"bbb","time_CET":"00:30:00", "VAL": 280}, ->0.8*350
{"ID":"bbb","time_CET":"00:45:00", "VAL": 315}, ->0.9*350
{"ID":"ccc","time_CET":"00:00:00", "VAL": 100}, ->0.5*200
{"ID":"ccc","time_CET":"00:15:00", "VAL": 140}, ->0.7*200
{"ID":"ccc","time_CET":"00:30:00", "VAL": 160}, ->0.8*200
{"ID":"ccc","time_CET":"00:45:00", "VAL": 180}, ->0.9*200
{"ID":"ddd","time_CET":"00:00:00", "VAL": 95}, ->0.5*190
{"ID":"ddd","time_CET":"00:15:00", "VAL": 133}, ->0.7*190
{"ID":"ddd","time_CET":"00:30:00", "VAL": 152}, ->0.8*190
{"ID":"ddd","time_CET":"00:45:00", "VAL": 171}, ->0.9*190
]
所以我不确定这是否可行。也许我必须将比率数组重塑为对象? (具有“time_cet”键且不是值数组的对象)。
无论如何,使用jq(也许是linux bash)实现这一目标的最佳方法是什么?谢谢!
更新:两种解决方案现在都有效,非常感谢。 这可能是另一个主题,但我想添加一个错误处理程序来捕获异常,特别是对于RATIO数组。 可能会发生这个数组
1.不包含指定索引/未定义的值
2.Value不是整数
无论如何我想为VAL设置一个默认值。错误消息应该记录在另一个文件中,如果可能的话..(我可以在这里使用当前日期吗? - >也许可以发送到STDERR?)Thx。
答案 0 :(得分:0)
假设以下jq程序在一个文件中,比如program.jq,那么调用:
jq --argfile ratio ratio.json --argfile constants constants.json -f program.jq data.json
产生所需的结果,至少在使用jq 1.5或更高版本时:
# r should be an array of ratios
# input is assumed to be an object with .time_CET
def getRatio(r):
if .time_CET=="00:00:00" then r[0]
elif .time_CET=="00:15:00" then r[1]
elif .time_CET=="00:30:00" then r[2]
else r[3]
end
;
def todict: reduce .[] as $o ({}; . + ($o | { (.ID): .CONST }));
def extend(r):
($constants|todict)[.ID] as $c
| .VAL = getRatio(r) * $c
;
($ratio[0] | .RATIO) as $RATIO
| map(extend($RATIO))
答案 1 :(得分:0)
这是一个解决方案:
# recent versions of jq include this in builtin.jq.
# we redefine it here in case it's not present
def INDEX(stream; idx_expr):
reduce stream as $row (
{}
; .[$row|idx_expr|if type != "string" then tojson else . end] |= $row
)
;
# make an array of all the times that appear in time_CET
def datatimes:
[$data[].time_CET] | unique[]
;
# make an object mapping time_CET to ratios
def time_to_ratio:
reduce datatimes as $i (
{}
; .[$i] = $ratio[0].RATIO[length]
)
;
# main procedure here
INDEX($constants[];.ID) as $ctable
| time_to_ratio as $rtable
| $data
| map(.VAL = $ctable[.ID].CONST * $rtable[.time_CET])
如果此过滤器位于filter.jq
且其他数据分别位于constants.json
,ratio.json
和data.json
文件中,则命令
jq -Mnc \
--argfile constants constants.json \
--argfile data data.json \
--argfile ratio ratio.json \
-f filter.jq
产生
[
{
"ID": "aaa",
"time_CET": "00:00:00",
"VAL": 125
},
{
"ID": "aaa",
"time_CET": "00:15:00",
"VAL": 175
},
{
"ID": "aaa",
"time_CET": "00:30:00",
"VAL": 200
},
{
"ID": "aaa",
"time_CET": "00:45:00",
"VAL": 225
},
{
"ID": "bbb",
"time_CET": "00:00:00",
"VAL": 175
},
{
"ID": "bbb",
"time_CET": "00:15:00",
"VAL": 244.99999999999997
},
{
"ID": "bbb",
"time_CET": "00:30:00",
"VAL": 280
},
{
"ID": "bbb",
"time_CET": "00:45:00",
"VAL": 315
},
{
"ID": "ccc",
"time_CET": "00:00:00",
"VAL": 100
},
{
"ID": "ccc",
"time_CET": "00:15:00",
"VAL": 140
},
{
"ID": "ccc",
"time_CET": "00:30:00",
"VAL": 160
},
{
"ID": "ccc",
"time_CET": "00:45:00",
"VAL": 180
},
{
"ID": "ddd",
"time_CET": "00:00:00",
"VAL": 95
},
{
"ID": "ddd",
"time_CET": "00:15:00",
"VAL": 133
},
{
"ID": "ddd",
"time_CET": "00:30:00",
"VAL": 152
},
{
"ID": "ddd",
"time_CET": "00:45:00",
"VAL": 171
}
]