Next: , Previous: cat -b, Up: Examples


4.9 文字を数える

以下のスクリプトは,sedで算数を行なうもう一つの方法を提示して います.この状況では,我々は可能な限り大きな数を追加する必要があるので, これを正しく増加するように実装することは不可能でしょう(そして,おそらく このスクリプトより計算がより複雑になるでしょう).

数字を文字に割り当てるアプローチは,sedを用いたソロバンの実装 の一種です.‘a’は一の位,‘b’は十の位などになっています.我々 は,一の位として現在の行に文字の数を単純に追加し,十の位,百の位などに 繰り上げ伝搬させています.

通常通り,実行時の総数はホールド空間に保持されます.

最後の行で,ソロバンを十進数の形式に戻しています.多様性のため,これは 80のsコマンドではなく,ループを用いて行なっています1.最初 に一の位を変換し,‘a’を数値から削除します.そして十の位が‘a’ になるように文字を回転させ,残っている文字が無くなるまでそれを続けます.

     #!/usr/bin/sed -nf
     
     # Add n+1 a's to hold space (+1 is for the newline)
     s/./a/g
     H
     x
     s/\n/a/
     
     # Do the carry.  The t's and b's are not necessary,
     # but they do speed up the thing
     t a
     : a;  s/aaaaaaaaaa/b/g; t b; b done
     : b;  s/bbbbbbbbbb/c/g; t c; b done
     : c;  s/cccccccccc/d/g; t d; b done
     : d;  s/dddddddddd/e/g; t e; b done
     : e;  s/eeeeeeeeee/f/g; t f; b done
     : f;  s/ffffffffff/g/g; t g; b done
     : g;  s/gggggggggg/h/g; t h; b done
     : h;  s/hhhhhhhhhh//g
     
     : done
     $! {
       h
       b
     }
     
     # On the last line, convert back to decimal
     
     : loop
     /a/! s/[b-h]*/&0/
     s/aaaaaaaaa/9/
     s/aaaaaaaa/8/
     s/aaaaaaa/7/
     s/aaaaaa/6/
     s/aaaaa/5/
     s/aaaa/4/
     s/aaa/3/
     s/aa/2/
     s/a/1/
     
     : next
     y/bcdefgh/abcdefg/
     /[a-h]/ b loop
     p

Footnotes

[1] 実 装によっては,スクリプトごとのコマンドが199に制限されています.