前回、こんな記事を書きました。
この記事では、エラーの原因になっていた見えない「U+0008」という文字をテキストエディタを使う事で視認することはできました。
しかし、この文字を元々どんな用途で使うものなのかは知らなかったので、次は「こいつは何者なのか?」を確認します。
「U+0008」とは?
Unicodeに属している文字である
まずUnicodeという文字の集合があり、その中のU+0008という1つの文字を表すものです。例えば、あ
という平仮名は、Unicodeの文字集合ではU+3042に該当します。
U+XXXXと書くことで、Unicodeの中で何の文字を指すのかを表現できます。これをUnicodeのコードポイントと呼びます。
Unicodeのコードポイント一覧はこちら
ちなみにUnicode(文字集合)は、UTF-8・UTF-16など(符号化方式)とは違う概念です。私は理解が曖昧でしたので、こちらを参考にして理解しました。
「U+0008」の意味
U+0008は「BackSpace(後退)」を表していて、ターミナル上では入力カーソルの現在位置を後退させる意味を持ちます。
ShellScriptでは\b
と打つとこのBackSpaceの意味になります。試しに、123\b45
という文字列をMacのターミナルとファイルにそれぞれ出力してみました。
$ echo -e "123\b45" # 標準出力
1245
$ echo -e "123\b45" > backspase.txt # ファイル出力
$
標準出力では\b
の直前にあった3
が表示されず、1245
と描画されています。
一方、リダイレクトでファイル出力したbackspase.txtをSublimeTextで開くと、3
とBS
と表現される特殊な文字が保存されていることが確認できます。
このコマンドのターミナル上での処理の流れは以下のようになります。|
は入力カーソルの位置を表現しています。
| # 初期状態
123| # 123を描画
12|3 # カーソルを1文字分後退させて、2と3の間に移動
1245| # 移動先のカーソル位置から45を描画する(3を上書き)
このようにBackSpaceを使うと、描画した領域を再度利用して同じ行で違う文字に更新させることができます。
もう少し詳しく見てみると、以下のような動きをします。
$ echo -e "123\b" # カーソル位置が後退するだけで、文字の削除はしない
123
$ echo -e "123\b\b45" # BackSpaceの数だけカーソル位置が後退する
145
$ echo -e "123\b\b4" # 狙った場所だけ更新できる(2を4に更新)
143
$
この文字の使い道として例えば、以下で示すターミナル上でファイルダウンロードなどの進捗率を表現する時などに使われます。
「U+0008」を使ったサンプルプログラム
以下のプログラムは、U+0008(BackSpace)を使って進捗率をターミナル上で再描画しながら更新する例です。
処理内容は、1秒毎に数字を1から10まで1ずつ増加させながら、BackSpaceを使用して同じ位置にその数字(進捗率)を再描画しているだけです。ヒアドキュメントで書いたプログラムをshコマンドに直接食わせる形になってます。
sh << EOD
printf "progress: 0%%\b\b" # 進捗しても変化しない部分を描画して、カーソルを更新部分まで後退させる
for i in \$(seq 1 10) # iを1から10までループ
do
sleep 1s # 1秒スリープ
printf "\b\b%2s" \${i} # カーソルを後退させ、i(進捗率)だけを上書きする
done
printf "\n"
EOD
こんな感じで動きます。ターミナルにコピペすればそのまま実行できます。
まとめ
「U+0008」という文字は、Unicodeという文字集合の中の1つの文字で、BackSpace(後退)を表現しています。
これまでプログラムを書く際に、この文字を使った経験はありませんでした。サンプルプログラムのように処理の進捗状況をその場で更新する以外に使い道が思いつきませんが、何かもっとうまい使い方があるのかもしれません。