その他
    ホーム技術発信DoRubyMacOSX の 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 も入れておくと良いでしょう。