配列等を一定数で分割したい時、shellで書くよりもRubyのeach_sliceで書く方がワンライナーでスッキリ書ける。
例えば1から98までを5個区切りで表示したいとする。
まず、Rangeオブジェクトで1から98までを作成し、each_sliceを繋げて、5個ずつに分割する。
$ ruby -e '(1..98).each_slice(5){|arr| puts arr.join(" ")}'
1 2 3 4 5
6 7 8 9 10
(略)
91 92 93 94 95
96 97 98
割り切れない数でeach_sliceしても良いように分割してくれる。
例題をちょっと複雑にしてみる。No.1からNo.98までを5個区切りにし、some_commandというコマンドに引数として渡すスクリプトを文字列として出力する。
$ ruby -e '(1..98).map{|i| "No." + i.to_s}.each_slice(5){|arr| puts "some_command #{arr.join(" ")}" }'
some_command No.1 No.2 No.3 No.4 No.5
some_command No.6 No.7 No.8 No.9 No.10
(略)
some_command No.91 No.92 No.93 No.94 No.95
some_command No.96 No.97 No.98
出力されたスクリプトをコピペして実行してもいいし、| sh
としてshをパイプで繋げてそのまま実行してもいい。
some_commandがls -l
であったとすると、
$ ruby -e '(1..98).map{|i| "No." + i.to_s}.each_slice(5){|arr| puts "ls -l #{arr.join(" ")}" }' | sh
でNo.1からNo.98というファイルに対して、ls -l
の引数を5個ずつに分割して全部実行してくれる。