昨日のシェル芸ヴェンキョウカイ(問2)で話題になった、BSD系環境で制御コードを置換するはなしです。
sedではやれないけどtrなら……という話です。

An error occurred while retrieving the Tweet. It might have been deleted.

### 内容
#### 概要 問2の模範解答は ```sh comm <(sort a) <(sort b) | sed 's/^/\t/' | sed 's/\t\t\t/c /' | sed 's/\t\t/b /' | sed 's/\t/a /' | sort ```となっています。
これは「先頭にtabを突っ込んで、タブの連続を置換していく」という解き方で、GNU sedの利用を前提としています。今回は解説のため、まずはBSDのsedとtrを使った別解を書いてみます。
tabの代わりにカンマ(,)を使用するという発想です。 ```sh % comm <(sort a) <(sort b) | tr '\011' ',' | sed 's/^/,/' | sed 's/,,,/c /' | sed 's/,,/b /' | sed 's/,/a /' | sort a 川崎 a 鹿島田 b 南多摩 b 登戸 c 分倍河原 c 谷保 ```
#### trの部分の解説 trの前で止めるとこうなっていて ```sh % comm <(sort a) <(sort b) 分倍河原 南多摩 川崎 登戸 谷保 鹿島田 ```※commコマンドの話は後でしますが、データがタブ区切りになっていますtrの後で止めるとこうなっています。 ```sh % comm <(sort a) <(sort b) | tr '\011' ',' ,,分倍河原 ,南多摩 川崎 ,登戸 ,,谷保 鹿島田 ```
さて、manによると > \octal バックスラッシュに続き、1〜3 桁の 8 進数が続いたものは、その値 を符号化した文字を表現します。この 8 進数の並びに続いて数字を 文字として指定したい場合には、8 進数の並びが 3 桁となるよう に、8 進数の上位桁 (左) に 0 を埋めてください とのことです。つまり ```sh tr '\011' ',' ```は、ASCIIコードでtab(16進数で09、8進数で11)をカンマ(,)に置換する、ということになります。


#### どんでん返しその1 さっきの、sedのmanの続きです…… > \character バックスラッシュに続く、特定の特殊な文字は、特殊な値に対応しています。\a <ベル文字> \b <バックスペース> \f <フォームフィード> \n <改行> \r <復帰> \t <水平タブ> \v <垂直タブ> trは普通にバックスラッシュ文字が使えました……そういえばそうだった……
つまり ```sh % comm <(sort a) <(sort b) | tr '\t' ',' | sed 's/^/,/' | sed 's/,,,/c /' | sed 's/,,/b /' | sed 's/,/a /' | sort ```でいいってことですよ奥さん!! 

#### どんでん返しその2 ……ここまで書いといて何ですが、printf使えばsedでもやれます[FreeBSDのsedで\rを取り除く方法 - Qiita](http://qiita.com/kunst1080/items/f5e53885fe3de5546e7e)
```sh comm <(sort a) <(sort b) | sed "s/^/`printf '\t'`/" | sed "s/`printf '\t\t\t'`/c /" | sed "s/`printf '\t\t'`/b /" | sed "s/`printf '\t'`/a /" | sort ``` 
以上!