前回は、フィボナッチ数列を垂れ流すだけのfibsを使いたいが、fibsが終わらないと次に進まないのでできないという話でした。
しかし、Linuxにはパイプというものがあったはずです。これならfibsがある程度進めば、その下流の関数が動き出すはずです。そこで、適当にtakewhileっぽいものを書きます。
takewhile() { upper=$1 local x while read x; do if [ $x -gt $upper ]; then break fi echo $x done }
readは標準出力から1行読んでxに格納します。$xがtakewhileの引数の$upperより大きくなればbreakで打ち切られます。
そして、
N=$1 fibs | takewhile $N
とすれば、$N以下のフィボナッチ数列を列挙されます。
偶数でフィルターする関数も同様に書きます。そして、最後の和を取る部分は汎用的なのでファイルにします。sum.shを次のように書きます。
#!/bin/bash #sum.sh s=0 while read x; do let s+=x done echo $s
最後にこれらをパイプでつないで、
#!/bin/bash fibs() { local m=1 local n=1 while :; do echo $n local tmp=$n n=$((n+m)) m=$tmp done } takewhile() { local upper=$1 local x while read x; do if [ $x -gt $upper ]; then break fi echo $x done } filter_even() { local x while read x; do if [ $((x%2)) -eq 0 ]; then echo $x fi done } N=$1 fibs | takewhile $N | filter_even | ./sum.sh
local
関数内でlocalを使うとローカル変数になります。
#!/bin/bash f() { local n=1 let n+=1 } n=1 f echo $n # 1
#!/bin/bash f() { let n+=1 } n=1 f echo $n # 2