簡単にできるやろと思ったらそんなことなかったのでメモしておく
件数指定する
単純に件数を指定するだけであればlimit
でOK
$ echo '[1,2,3,4,5,6,7,8,9,10]' | jq 'limit(3; .[])' 1 2 3
これは簡単
絞り込みや並び替え後に件数指定する
上記のような単純な処理のみであれば問題ないのだが、select
を使いだすと何か処理させた後にパイプで渡ってくる値がどのような状態か意識しないとうまくいかなくなる
- リストから偶数を3件出力する
$ echo '[1,2,3,4,5,6,7,8,9,10]' | jq 'limit(3; .[]|select(.%2==0))' 2 4 6
- リストから偶数を降順で3件出力する(パターン1)
$ echo '[1,10,2,9,3,8,4,7,5,6]' | jq 'limit(3; [.[]|select(.%2==0)]|sort|reverse|.[])' 10 8 6
- リストから偶数を降順で3件出力する(パターン2)
echo '[1,10,2,9,3,8,4,7,5,6]' | jq '[.[]|select(.%2==0)]|sort|reverse|limit(3; .[])' 10 8 6
ポイントは下記のように外側の[]
でselectの結果を配列にしている箇所
[.[]|select(.%2==0)]
sortやlimitは配列を期待しているのでselectした結果をそのままパイプで渡すとうまくいかない
- うまくいかない例
$ echo '[1,10,2,9,3,8,4,7,5,6]' | jq '.[]|select(.%2==0)|sort|reverse|limit(3; .[])' jq: error (at <stdin>:1): number (10) cannot be sorted, as it is not an array
当たり前といえばそうなのだが、Ruby脳と組み合わさるとこのあたりの感覚が狂ってくる
まとめ
jqで配列を扱う場合はパイプで次の処理に渡すデータの単位を意識しよう