我有一个充满对象的管道,我试图添加一个累积计数字符串到jq
流中的每个对象,以获得以下输出
{"count":"Num_000"}
{"count":"Num_001"}
{"count":"Num_002"}
{"count":"Num_003"}
{"count":"Num_004"}
{"count":"Num_005"}
{"count":"Num_006"}
{"count":"Num_007"}
{"count":"Num_008"}
{"count":"Num_009"}
类似以下内容,但我确信我不需要依赖awk。
yes '{}' | head -n10 | jq -c '.count|="Num_ "' | awk '{printf("%s%03i%sn",$1,NR-1,$2)}'
到目前为止,我已经找到了一种方法来将计数输入到我的对象中,但是感觉非常浪费,因为我吸进了所有的对象。
yes '{}' | head -n10 | jq -c -s 'range(0;.|length) as $i|(.[$i]|.count|=$i)'
我要继续玩这个,但我认为这是我学习的机会。有什么办法我可以更有效地做到这一点吗?
我还想出了一种巧妙的方法来格式化字符串,因为我假设<我的流中有1000个对象>我的流中有1000个对象>
yes '{}' | head -n20 | jq -c -s 'range(0;.|length) as $i|(.[$i]|.count|=(1000+$i|tostring|ltrimstr("1")|"Num_"+.))'
使用jq的最新版本(即使用foreach和input),例如jq 1.5rc1,可以按照以下行高效且相当优雅地执行任务:
yes 1 | head -n10 |
jq -c -n 'foreach inputs as $line (0; .+1; {"count": "Num_(.)"})'
使用-s
(slurp)选项,您可以执行以下操作:
yes '{}' | head -n10 | jq -s 'to_entries | map(.value.count = .key)[].value'
但是,是的,正如你自己说的,吸吮是浪费;更糟糕的是,它会阻塞流。
你可以做的是,对于每个元素,压缩它,使它需要一行(管道通过jq -c '.'
;您的"yes"对象示例不需要它,但是来自管道的任意对象可能需要),然后在shell上遍历它。在鱼壳上,但很容易移植到其他任何地方:
set j 0
for i in (yes '{}' | head -n 100000 | jq -c '.')
set j (expr $j + 1)
echo $i | jq --arg j $j '.count = ($j | tonumber)'
end