出力を縦に折り返す

左の出力を右の出力にする foo を見つけたいと呟いたら、 Twitter で反応してくれた方が結構いた。
ありがたいです。


$ seq 10
1
2
3
4
5
6
7
8
9
10


$ seq 10 | foo
1 6
2 7
3 8
4 9
5 10

つまり、 fold の列バージョンがしたかった。

考えてたこと

三角行列みたいなものを作って、列をふたつ引っ張って来ればいけるのでは?

三角行列

こういう三角行列に整形してくれる bar を作れば、その出力に答えが埋まってる。

$ seq 10 | bar
1 2 3 4 5 6 7 8 9 10 
2 3 4 5 6 7 8 9 10 
3 4 5 6 7 8 9 10 
4 5 6 7 8 9 10 
5 6 7 8 9 10 
6 7 8 9 10 
7 8 9 10 
8 9 10 
9 10 
10
いい感じの二列
$ seq 10 | bar | awk '{print $1, $6}'
1 6
2 7
3 8
4 9
5 10
6
7
8
9
10

抽出に使った awk

右側の列指定が (NF+3)/2 -> NF/2+1.5 なのは、awk がゼロオリジンじゃないから 1 足す分と奇数のときに減るのをなくすための 0.5。

$ seq 10 | bar | awk '(NR<=NF){if(i==""){i=(NF+3)/2}print $1" "$i}'
1 6
2 7
3 8
4 9
5 10

三角行列はどうしたら得られるのか?

唐突に出てきた三角行列を作るための bar の部分について。

横にする

とりあえず、後段に使う予定の awk が要素数を NF で触れるようにするために横にする。

$ seq 10 | xargs
1 2 3 4 5 6 7 8 9 10 

二重ループ

二重ループで美しくないけど実現できるはず。

$ seq 10 | xargs |\
  awk '{for(i=1;i<=NF;i++){for(j=i;j<=NF;j++){printf($j" ")}print ""}}' 

awk ふたつ

$ seq 10 | xargs | awk '{for(j=1;j<=NF;j++){print $0}}' |\
  awk '{for(i=NR;i<=NF;i++){printf $i" "}print ""}'

まとめ

$ seq 10 | xargs | awk '{for(j=1;j<=NF;j++){print $0}}' |\
  awk '{for(i=NR;i<=NF;i++){printf $i" "}print ""}' |\
  awk '(NR<=NF){if(i==""){i=(NF+3)/2}print $1" "$i}'

他の方々のもの

ゆうくん (@takion0) | Twitter

Tukubai がないなら、`gyo tmp` -> `cat tmp | wc -l`。

くんすと (@kunst1080) | Twitter

ぐれさん (@grethlen) | Twitter

Heliac1999 (@Heliac1999) | Twitter

あれ・・・?