我有此命令,我想对输出中的所有数字求和。
命令如下所示
$(hadoop fs -ls -R /reports/dt=2018-08-27 | grep _stats.json | awk '{print $NF}' | xargs hadoop fs -cat | jq '.duration')
因此,它将列出/reports/dt=2018-08-27
中的所有文件夹,仅获取_stats.json
,并将其从jq
传递到hadoop -cat
,并从.duration
中获取json。最终我得到这样的结果。
1211789 1211789 373585 495379 1211789
但是我希望命令将所有这些数字加起来成为4504331
答案 0 :(得分:14)
最简单的解决方案是add
过滤器:
jq '[.duration] | add'
需要用[
括起来的括号]
用于求和,因为add
是对 array 而不是流的值求和。 (对于流求和,您将需要更复杂的解决方案,例如使用reduce
,如其他答案中所述。)
根据输入的确切格式,您可能需要进行一些预处理才能实现此目的。
例如输入Charles Duffy’s answer中的示例输入
使用inputs
(请注意,{j {1}}可以避免jq吞没输入的第一行):
-n
或草率(jq -n '[inputs.duration] | add' <<< "$sample_data"
)并迭代(-s
):
.[]
答案 1 :(得分:5)
另一种方法(即使并非所有持续时间都为整数,该方法也可以使用)是使您的jq
代码起作用:
sample_data='{"duration": 1211789}
{"duration": 1211789}
{"duration": 373585}
{"duration": 495379}
{"duration": 1211789}'
jq -n '[inputs | .duration] | reduce .[] as $num (0; .+$num)' <<<"$sample_data"
...正确发出作为输出:
4504331
根据需要在标准输入上用管道替换<<<"$sample_data"
。
答案 2 :(得分:2)
您现在就可以使用add
。
jq '.duration | add'
答案 3 :(得分:1)
awk
来营救!
$ ... | awk '{sum+=$0} END{print sum}'
4504331
答案 4 :(得分:1)
为了清楚和通用起见,可能值得定义sigma(s)
以添加数字流:
... | jq -n '
def sigma(s): reduce s as $x(0;.+$x);
sigma(inputs | .duration)'
答案 5 :(得分:0)
使用for
循环。
total=0
for num in $(hadoop fs -ls -R /reports/dt=2018-08-27 | grep _stats.json | awk '{print $NF}' | xargs hadoop fs -cat | jq '.duration')
do
((total += num))
done
echo $total
答案 6 :(得分:0)
结合其他答案。
$ jq -n '[inputs | .duration] | add' <<< "$sample_data"
# 4504331
在用[inputs | .duration]
求和之前,我必须格式化数组add
中的值。