問題編
テキストデータを、改行区切りのテキストレコードに埋め込んで出力したい。例えばusp Tukubaiでいうところのネーム形式やフィールド形式のフィールドの値として出力したい。
問題は、元データに改行が含まれている可能性があることだ。また、フィールド形式の場合、元データに空白文字が含まれている可能性も見逃せない。フィールドに埋め込む前に、改行や空白文字をエスケープする必要がある。
C言語系統の言語やUnix環境のツールのように「\n」のような記号を使用するのは、可読性の面では望ましい。しかし、この手のエスケープ記号を使って手作業でデータを作ることや、エスケープ記号を処理するコードを書くのは難しくないのだが、エスケープを行うコードを書くのは少々面倒だ*1。
また、フィールドのセパレータに関しては、空白文字以外にも「:」とか「|」とか「,」とかありえる訳で、記号が変わるたびにエスケープの処理を拵えるのも面倒だ。
何か別のアイデアはないだろうか?
解答編(暫定)
少々大胆な仮定をしてみることにした。
- セパレータとして使用される可能性がある文字は、空白文字か記号文字だけである。
この仮定の下では、フィールドの値として無条件に使用できるのは数字か普通の文字(ASCII文字でいうところのアルファベット文字)のみである。
いちいちエスケープが必要な部分を探して変換するのは面倒なので、16進ダンプしてしまうことにする。
元のデータを16進ダンプするのは難しくない。
# od(1) と tr(1) は大抵の環境に用意されているはず echo -n hello world | od -A n -t x1 -v | tr -d ' ' # => 68656c6c6f20776f726c64 # hexdump(1) は時々標準では入ってないことがある echo -n hello world | hexdump -v -e '2/1 "%02X"' # => 68656C6C6F20776F726C64
16進ダンプから元に戻す処理については、手ごろなテキストフィルタが見つからなかったので、自作してみた。
https://github.com/eel3/hexdecode
上記のコマンドを使用して、データをテキストレコードのフィールドに埋め込む前に16進ダンプしておき、レコードからフィールドを取り出す際にデコードして元に戻すようにする。
16進ダンプ案の前にbase64(1)を使うことも考えたが、「+」や「/」が出現することは容認できたが、LinuxとMac OS Xとでオプション引数が異なることは容認できなかった。