Quantcast
Channel: Bashタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 2912

シェルスクリプトで二次元の九九一覧表を作ってみた(pasteによるn個ごとの折返し)

$
0
0
はじめに いろいろと思いつくままに書いてみました。実は paste コマンドのちょっとめずらしい(?)使い方の紹介です。 ※ paste コマンドは他のコマンドに比べてあまり有名ではありませんが POSIX で規定されたコマンドです。 出力結果 1*1=1 1*2=2 1*3=3 1*4=4 1*5=5 1*6=6 1*7=7 1*8=8 1*9=9 2*1=2 2*2=4 2*3=6 2*4=8 2*5=10 2*6=12 2*7=14 2*8=16 2*9=18 3*1=3 3*2=6 3*3=9 3*4=12 3*5=15 3*6=18 3*7=21 3*8=24 3*9=27 4*1=4 4*2=8 4*3=12 4*4=16 4*5=20 4*6=24 4*7=28 4*8=32 4*9=36 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 5*6=30 5*7=35 5*8=40 5*9=45 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 6*7=42 6*8=48 6*9=54 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 7*8=56 7*9=63 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 8*9=72 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81 seq seq 9 | while read i; do seq -f "$i*%0g" 9 done | while read a; do eval 'echo $a=$(($a))' done | paste - - - - - - - - - 備考 seq が POSIX 準拠ではない ブレース展開 printf '%s\n' {1..9}"*"{1..9} | while read a; do eval 'echo $a=$(($a))' done | paste - - - - - - - - - 備考 ブレース展開が POSIX シェル準拠ではない for for i in 1 2 3 4 5 6 7 8 9; do for j in 1 2 3 4 5 6 7 8 9; do echo "$i*$j=$((i*j))" done done | paste - - - - - - - - - 備考 POSIX 準拠。9 個ぐらいならそのまま値を書いていいよね? while i=0 while [ "$i" -lt 9 ] && i=$((i+1)) j=0; do while [ "$j" -lt 9 ] && j=$((j+1)); do echo "$i*$j=$((i*j))" done done | paste - - - - - - - - - 備考 POSIX 準拠。無理やり詰め込んで行数を少なくしてみた 計算マニア i=0 while [ "$i" -lt 81 ]; do echo "$(( i/9+1 ))*$(( i%9+1 ))=$(( (i/9+1) * (i%9+1) ))" i=$((i+1)) done | paste - - - - - - - - - 備考 POSIX 準拠。ここまでして二重ループを削除する必要はあるか?(ない) bc for i in 1 2 3 4 5 6 7 8 9; do for j in 1 2 3 4 5 6 7 8 9; do echo "\"$i*$j=\"; $i*$j" done done | bc | paste - - - - - - - - - 備考 Bourne シェルでも動く expr を使ってもできますがループで毎回外部コマンドを呼び出すと遅くなるので、計算式を bc コマンドに与えることで高速化しています。(参考 シェルスクリプトのための良いデザイン ~ expr と bc から知る設計の違い ~) paste 使わない for i in 1 2 3 4 5 6 7 8 9; do for j in 1 2 3 4 5 6 7 8 9; do printf "%d*%d=%-2d " "$i" "$j" $((i*j)) done echo done さいごに ということで九九一覧表の作り方のふりをした「paste コマンドは、一般的には引数の複数のファイルを一行ずつ読み取って組み合わせて出力するコマンドですが、標準入力からの入力(-)を使うと n 個ごとに折り返すことができます」という記事でした。 一般的な使い方 $ cat foo.txt foo1 foo2 foo3 # bar.txt と baz.txt も同様 $ paste foo.txt bar.txt baz.txt foo1 bar1 baz1 foo2 bar2 baz2 foo3 bar3 baz3 この記事で紹介した使い方 $ seq 10 | paste - - - 1 2 3 4 5 6 7 8 9 10 このような使い方は POSIX でも紹介されています。(ls の出力結果を 4 つのカラムで出力する例) Write out a directory in four columns:ls | paste - - - - さて、他にもなにか面白い九九一覧表の作り方ないかな?

Viewing all articles
Browse latest Browse all 2912

Trending Articles