ホーム DoRuby MacOSX の sed に気をつけろ

MacOSX の sed に気をつけろ

この記事はアピリッツの技術ブログ「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 も入れておくと良いでしょう。

記事を共有

最近人気な記事