7.13 文字数のカウント

このスクリプトは、sedで算術演算を行う別の方法を示します。今回は、大きいかもしれない数値を足す必要があるため、1ずつ増やす処理を繰り返す方法は現実的ではありません(しかも、このスクリプトより組み立てが複雑になるかもしれません)。

ここでは、数値を文字に対応させます。sedで実装したそろばんのようなものです。「a」が一の位、「b」が十の位、といった具合です。現在の行の文字数を一の位に足し、その後、十の位、百の位へと繰り上がりを伝えます。

いつものように、累計はホールドスペースに保持します。

最終行で、そろばん形式を十進数へ戻します。変化を付けるため、80個ほどのsコマンド11ではなくループを使います。まず一の位を変換し、数値から「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/
コード内の説明(日本語訳)

n+1個のaをホールドスペースへ追加します(+1は改行の分です)。


# 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
コード内の説明(日本語訳)

繰り上がりを処理します。tとbは必須ではありませんが、処理を高速化します。


: 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

(11)

実装によっては、スクリプト1つにつき199コマンドという制限があります。