この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
こんにちは、たろちゃんです。
先日、MacOSX で sed コマンドを使って置換を行った時にはまってしまったので、それについて書きます。
例えば、以下のようなテキストがCR+LFで保存されていたとします。
egg
spam
ham
これをspamの置換してspamを三行追加しようとします。つまりこういう状態を目指します。
egg
spam
spam
spam
ham
では早速やってみましょう。CR+LFなので改行文字は\r\nとします。
$ sed -e 's/spam/spam\r\nspam\r\nspam/' spam.txt > spam2.txt
すると、こんなテキストファイルができあがってしまいます。
egg
spamrnspamrnspam
ham
改行文字が普通の文字列として認識されてしまいます。これは GNU の sed コマンドではなく FreeBSD 由来の sed コマンドであるからのようです。
ちょっと違う方法でやってみましょう。あまり一般的ではない改行を sed -e に入れる方法です。
sed -e 's/spam/spam\
> spam\
> spam/' spam.txt > spam3.txt
lvなどで確認すると期待通りの結果が得られたように見えますが文字コードを見るとCR+LFとLFが混在してしまっています。
$ od -c spam3.txt
0000000 e g g \r \n s p a m \n s p a m \n s
0000020 p a m \r \n h a m \n
というわけで、素直に GNU 版 sed を導入する事にしましょう。
筆者はMac Portsを導入しているので、portコマンドから探しました。
$ port search sed
...
gsed textproc/gsed 4.1.5 GNU version of the stream editor, sed
ssed textproc/ssed 3.62 Super-sed - a heavily enhanced version of sed
gsed というのが GNU 版に該当するようなので、インストールしてみます。
$ sudo port install gsed
インストールが完了したらあとは gsed コマンドで最初の方法を試してみます。
$ gsed -e 's/spam/spam\r\nspam\r\nspam/' spam.txt > spam4.txt
さっそく文字コードを確認してみましょう。
$ od -c spam4.txt
0000000 e g g \r \n s p a m \r \n s p a m \r
0000020 \n s p a m \r \n h a m
これで納得した結果が得られました。
Web 上によく掲載されている例は GNU 版の sed コマンドを利用しています。MacOSX を使っている方で shell を良く使う人は GNU 版の sed も入れておくと良いでしょう。