WindowsでCRLFからLFに一括変換する


windowsでpowershellかgit-bashを使ってCRLFからLFに一括変換する方法を紹介しています。
(追記)gitで管理されている場合、もっと簡単な方法がありました。

発端

Windowsでdockerのコンテナをビルド、起動した所、以下の様なエラーが発生した。

standard_init_linux.go:190: exec user process caused "no such file or directory"

調べるとどうやら、コンテナにコピーした設定ファイルの改行コードがCRLFになっているためエラーが発生している模様。
(コンテナはLinuxベースなので改行コードがLFである必要があった)

そんな訳でWindows上でCRLFからLFに一括変換する方法を調べた

(追記)Gitで管理されている場合

.gitattributesで改行コードを指定してファイルをチェックアウトしなおす事でまとめてLFにできます。
詳しい手順は以下の通りです。

まずは全てのファイルをコミットして差分が無い状態にします。
続いてリポジトリのルートに.gitattributesを追加し、各ファイルの改行コードを指定します。

* text=auto eol=lf

上記の意味は「gitがテキストファイルと判断するものは全て改行コードをLFとする」です。
詳しい記述方法はこちらの記事が分かりやすいです。

その後、CRLFになってしまっているファイルを一旦削除した後、
git checkout -fで復活させると改行コードがまとめてLFになっています。

これが一番簡単だしクローンするたびに再設定しなきゃいけないなんて事もないのでオススメです。

Git-bashが使える場合

git-bashが使える場合、linuxのコマンドが使えるので簡単です。
以下のコマンドで、カレントフォルダ以下のファイルをCRLFからLFに一括変換できます。

find * -type f -exec sed -i "s/\\r\\n/\\n/g" {} \;

以下、コマンドの解説です。

  • find . -type f -exec {} \;
    • カレントフォルダ以下のファイルを列挙します。
    • -type fでファイルのみに制限します。
    • -execは列挙したファイルを別のコマンドに渡します。ここではsedコマンドに渡しており、{}にはファイル名が埋め込まれます。\;はコマンドの終端を表すおまじないです。
  • sed -i "s/\\r\\n/\\n/g" [ファイル名]
    • CRLFをLFに置換します。
    • -iを指定する事によりファイルを直接編集します。(付けない場合、処理結果が標準出力に出力されます)

Git-bashが使えない場合

git-bashが使えない場合、Windows標準の機能でやる事になります。
今回はpowershellを使う事にします。
以下のコマンドで、カレントフォルダ以下のファイルをCRLFからLFに一括変換できます。

Get-ChildItem -Recurse -File | ForEach-Object {((Get-Content $_.FullName -Raw) -replace "`r`n","`n") | Set-Content $_.FullName}

以下、コマンドの解説です。

  • Get-ChildItem -Recurse -File
    • ファイルの一覧を取得します。
    • ここのオプションを変更すれば対象範囲を制御できるかと思います。
  • ForEach-Object { ... }
    • 各ファイルに{}の中のコマンドを適応します。
    • $_.FullNameにファイルパスが展開されます。
  • Get-Content $_.FullName -Raw
    • ファイルを読みこみます。
    • -Rawを付与することで1つの文字列として読み込みます。付与しないと各行の配列として読み出されてしまい改行コードが失われてしまいます。
  • "文字列" -replace "`r`n","`n"
    • CRLFをLFに置換しています。
    • PowerShellのエスケープ文字は`なので注意してください。(見慣れませんね)
  • Set-Content $_.FullName
    • ファイルを書き込みます。

以上です。
PowerShellの書き方になれてなくて手間取りました