2015-06-01 306 views
0

我已經有了一個完整的對象的管,我試圖將積累數字符串流添加到每個對象與jq得到以下輸出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%s\n",$1,NR-1,$2)}' 

到目前爲止,我已經找到一個方式來獲得計數到我的對象,但因爲我啜了所有的對象,感覺很浪費。

yes '{}' | head -n10 | jq -c -s 'range(0;.|length) as $i|(.[$i]|.count|=$i)' 

我要繼續玩這個,但我想這是我學習的機會。任何想法如何我可以更有效地做到這一點?

我也想出了一種hack-y方式來格式化字符串,因爲我假設在我的流中有1000個對象。

yes '{}' | head -n20 | jq -c -s 'range(0;.|length) as $i|(.[$i]|.count|=(1000+$i|tostring|ltrimstr("1")|"Num_"+.))' 

回答

1

使用-s(啜食)的選項,你可以做到以下幾點:

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 
1

使用最新JQ的版本(即用foreach和輸入),如JQ 1.5rc1,可以有效地和相當優雅的大意如下執行的任務:

yes 1 | head -n10 |\ 
jq -c -n 'foreach inputs as $line (0; .+1; {"count": "Num_\(.)"})' 

這裏的關鍵是使用-n選項。