Windowsのsedで置換して変わった改行コードをLFからCRLFに戻す方法


  • 環境
    • OS : Windows10 64bit
    • Git Bash : 2.12.2.2
    • od (GNU coreutils) 8.26
    • sed (GNU sed) 4.4
    • nkf : Network Kanji Filter Version 2.1.1 (2010-08-08)
    • GNU Awk 4.1.4, API: 1.1 (GNU MPFR 3.1.5-p2, GNU MP 6.1.2)

GNUのsed で置換をすると改行コードは LF になる

GNUのsedを使うと改行コードが変わる
# sed で置換する前の改行コードは CRLF(\r\n)
$ od -c ~/Evernote/Logs/AppLog_2018-09-04.txt
0000000   *   *   *   *   *   *   *   *  \r  \n   *       T   h   e
0000020   A   c   t   i   v   i   t   y       L   o   g       c   o   n
0000040   t   a   i   n   s       a       d   e   t   a   i   l   e   d
0000060       l   i   s   t       o   f       t   h   e       s   t   e
0000100   p   s       t   h   e       E   v   e   r   n   o   t   e
0000120   a   p   p   l   i   c   a   t   i   o   n       p   e   r   f
0000140   o   r   m   s   ,  \r  \n   *       a   s       w   e   l   l
<省略>

# sed を上書きで実行する
$ sed -i 's/*/-/g' ~/Evernote/Logs/AppLog_2018-09-04.txt

# sed で置換した後の改行コードは LF(\n)
$ od -c ~/Evernote/Logs/AppLog_2018-09-04.txt
0000000   -   -   -   -   -   -   -   -  \n   -       T   h   e       A
0000020   c   t   i   v   i   t   y       L   o   g       c   o   n   t
0000040   a   i   n   s       a       d   e   t   a   i   l   e   d
0000060   l   i   s   t       o   f       t   h   e       s   t   e   p
0000100   s       t   h   e       E   v   e   r   n   o   t   e       a
0000120   p   p   l   i   c   a   t   i   o   n       p   e   r   f   o
0000140   r   m   s   ,  \n   -       a   s       w   e   l   l       a

sedは読み込んだ行の行末にある改行を削除してパターンスペースと呼ばれるバッファに格納したうえでテキスト処理をし、最後にパターンスペースの内容に改行をつけて出力する。
sedで改行を含む複数行の文字列を置換

BSDのsedは変わらない

  • 環境
    • OS:macOS High Sierra バージョン10.13.6
    • sed:BSDのsed
# sed で置換する前の改行コードは CRLF(\r\n)
$ od -c ~/Desktop/shell_kind.sh 
0000000    #   !   /   b   i   n   /   b   a   s   h  \r  \n  \r  \n   c
0000020    a   n   u   s   e   =   `   c   a   t       /   e   t   c   /
0000040    s   h   e   l   l   s   `  \r  \n   e   c   h   o       '  使
0000060   **  **  用  **  **  可  **  **  能  **  **  な  **  **  シ  **
0000100   **  ェ  **  **  ル  **  **  の  **  **  種  **  **  類  **  **
0000120   :  **  **   '   "   $   c   a   n   u   s   e   "  \r  \n   e
0000140    c   h   o       '  使  **  **  っ  **  **  て  **  **  い  **
0000160   **  る  **  **  シ  **  **  ェ  **  **  ル  **  **  の  **  **
0000200   種  **  **  類  **  **  :  **  **   '   $   S   H   E   L   L
0000220   \r  \n   e   c   h   o       '  今  **  **  動  **  **  か  **
0000240   **  し  **  **  て  **  **  い  **  **  る  **  **  シ  **  **
0000260   ェ  **  **  ル  **  **  の  **  **  名  **  **  前  **  **  :
0000300   **  **   '   $   0  \r  \n                          

# sed を上書きで実行する
$ sed -i '' 's/シェル/shell/g' ~/Desktop/shell_kind.sh

# sed で置換した後の改行コードも CRLF(\r\n)
$ od -c ~/Desktop/shell_kind.sh
0000000    #   !   /   b   i   n   /   b   a   s   h  \r  \n  \r  \n   c
0000020    a   n   u   s   e   =   `   c   a   t       /   e   t   c   /
0000040    s   h   e   l   l   s   `  \r  \n   e   c   h   o       '  使
0000060   **  **  用  **  **  可  **  **  能  **  **  な  **  **   s   h
0000100    e   l   l  の  **  **  種  **  **  類  **  **  :  **  **   '
0000120    "   $   c   a   n   u   s   e   "  \r  \n   e   c   h   o    
0000140    '  使  **  **  っ  **  **  て  **  **  い  **  **  る  **  **
0000160    s   h   e   l   l  の  **  **  種  **  **  類  **  **  :  **
0000200   **   '   $   S   H   E   L   L  \r  \n   e   c   h   o       '
0000220   今  **  **  動  **  **  か  **  **  し  **  **  て  **  **  い
0000240   **  **  る  **  **   s   h   e   l   l  の  **  **  名  **  **
0000260   前  **  **  :  **  **   '   $   0  \r  \n 

方法1: sed を使う

$ sed -i 's/$/\r/g' ~/Evernote/Logs/AppLog_2018-09-04.txt
$ od -c ~/Evernote/Logs/AppLog_2018-09-04.txt
0000000   -   -   -   -   -   -   -   -  \r  \n   -       T   h   e
0000020   A   c   t   i   v   i   t   y       L   o   g       c   o   n
0000040   t   a   i   n   s       a       d   e   t   a   i   l   e   d
0000060       l   i   s   t       o   f       t   h   e       s   t   e
0000100   p   s       t   h   e       E   v   e   r   n   o   t   e
0000120   a   p   p   l   i   c   a   t   i   o   n       p   e   r   f
0000140   o   r   m   s   ,  \r  \n   -       a   s       w   e   l   l

参考:Unix→Windowsに改行コード変換 - Qiita
参考:sedで改行を置換・削除する | 俺的備忘録 〜なんかいろいろ〜
参考:ファイル内の改行を削除, 連続した空白を1つにする - Qiita

方法2: nkf32 を使う

windows用の nkf32 を入れて使う

$ nkf32 -Lw -c --overwrite ~/Evernote/Logs/AppLog_2018-09-04.txt
$ od -c ~/Evernote/Logs/AppLog_2018-09-04.txt
0000000   -   -   -   -   -   -   -   -  \r  \n   -       T   h   e
0000020   A   c   t   i   v   i   t   y       L   o   g       c   o   n
0000040   t   a   i   n   s       a       d   e   t   a   i   l   e   d
0000060       l   i   s   t       o   f       t   h   e       s   t   e
0000100   p   s       t   h   e       E   v   e   r   n   o   t   e
0000120   a   p   p   l   i   c   a   t   i   o   n       p   e   r   f
0000140   o   r   m   s   ,  \r  \n   -       a   s       w   e   l   l

参考:文字コードと改行コードの変換 【nkf】
[参考:nkfで上書きする方法: 小粋空間」(http://www.koikikukan.com/archives/2016/11/28-011111.php)

方法3:変換ツールを使う

FileCode Checker の評価・使い方 - フリーソフト100

方法4:使い慣れたエディタの機能を使う

SublimeText3やサクラエディタなど改行コードを変更できるエディタは多い。