プログラムdeタマゴ

nodamushiの著作物は、文章、画像、プログラムにかかわらず全てUnlicenseです

Windowsでフォルダ内のファイルの改行コードを一括変換

 ディレクトリ内のファイルがメモ帳で改行が表示されない形式(LFかCR)だからCR+LFのWindows形式に一括変換したい。しかし、sedはおろか、shell環境も、エディタもない。メモ帳程度。ハゲそう。
 そんなときでもPowerShellさえあれば、一括変換出来るので、メモメモ。

Windows形式(CR+LF)に変換

 以下を実行すると、全てのファイルやディレクトリに対して処理するので注意。特定のファイルだけにしたい場合は後述のfilterを使う。

ls | foreach{ (cat $_) -join "`r`n" | set-content $_ }

 なお、文字コードは元のファイルが何であれ、Shift-JIS(正確にはパソコン環境依存)になる模様。UTF8で保存したい場合は、Set-Contentのオプション「-encoding UTF8」を利用する。

(ただし、PowerShell6からはBOMが付かなくなったので、6以上を使うことをお勧めします。ない場合は諦めてBOM食ってろ)

ls | foreach{ (cat -encoding UTF8  $_ ) -join "`r`n" | set-content -encoding UTF8 $_ }

 PowerShell2で文字化けしたことがあるので、catの方も付けといた方が無難かも知れない。5でも元と異なるフォーマットで保存しようとすると文字化けする模様。
 今のところ、PowerShell6では文字化けしたことはない。6いいね。

 (PowerShellはエセShellで、 |は並列起動しないのでこんな書き方が可能らしい)

Unix形式(LF)に変換

ls | foreach{ (cat $_) -join "`n" | set-content $_ }

Mac形式(CR)に変換

ls | foreach{ (cat $_) -join "`r" | set-content $_ }

特定の拡張子のファイルのみ変換したい場合

 grepとかなくても、ls(Get-ChildItem)のオプションにfilterがあるので、それで簡単なgrepできる。

例:拡張子が.txtだけを変換したい場合

ls -filter *.txt | foreach{ (cat $_ ) -join "`r`n" | set-content $_ }

サブディレクトリも再帰的に変換する場合

 lsコマンドがちょっと長くなる。

ls -r -n -file | foreach{ (cat $_ ) -join "`r`n" | set-content $_ }

 -r(-Recurse)で再帰化して、-n(-Name)で名前だけ出力させて、-fileでファイルだけをforeachに渡す。-filterの併用も可。

 cat(Get-Content)ってSystem.IO.FileSystemInfoをそのまま喰えないんだねぇ。

参考URL

www.atmarkit.co.jp
docs.microsoft.com

PowerShell実践ガイドブック ~クロスプラットフォーム対応の次世代シェルを徹底解説~

PowerShell実践ガイドブック ~クロスプラットフォーム対応の次世代シェルを徹底解説~