外注から送られてきたファイルにWindows形式の改行コードCRLF(以下dos形式)があるためにエラーが生じていたことが最近2度もありましたので、dos形式のファイルを検索/変換するコマンドを調べました。
dos形式ファイルを検索するコマンド
下記を実行することによって、カレントディレクトリ上のdos形式を使っているファイル名を列挙してくれます。
$ file * | grep CRLF | sed 's/:.*//g'
try_except.py
try_except.txt
try_except_else.py
viewfile.py
...省略
fileコマンドはファイル形式を調べてくれるコマンドです。grepによりCRLFを含む行だけフィルタしています。
既にシステムにコピーなどしている場合、
find /
と組み合わせるとファイルシステムの中全てを検索してくれます。
ルート
/
から調べると時間がかかりますので、/
を/usr
や/etc
に変えるなど、心当たりのあるディレクトリに絞った方が良いかもしれません。
root権限が必要かもしれません。
$ find / | xargs file | grep CRLF | sed 's/:.*//g'
find ... | xargs
はfind
で見つけ出したファイルに対してxargs
以下のコマンドを実行する、よく使う構文です。
参考: How to find dos format files in a linux file system
なお、最後のsedはファイル名以降に出てくるfileコマンドの出力をカットして見やすくしているだけですので、なくても動きますが、ない場合の表示が多少ごちゃつきます。
$ file * | grep CRLF
impoter.py Python script, UTF-8 Unicode text executable, with CRLF line terminators
...省略
# Python script...の部分が各行に対して追加されます。
dos形式をunix形式に変換するコマンド
トラブルの原因発覚当時はとりあえずの対処でVim上でdos形式 => unix形式を行いましたが、コマンドラインから一発で同じことができます。
一応手順を書いておくと、
$ vim temp.txt # temp.txtを開く
:se ff=unix " fileformat(略してffで通る)をunix形式にsetする(setも略してseで通る)
:wq " 保存して(w)終了(q)
dos2unix
,unix2dos
という外部コマンドもありますが、ディストロによって標準で入っていないこともある(=別途インストール必要)ので、ここではあえて使いません。
(本題ここから)
下記コマンドではtempdos.txt
というdos形式ファイルをtempunix.txt
というunix形式のファイルに変換しています。
$ tr -d '\r' < tempdos.txt > tempunix.txt
tr
の-d
オプションはdeleteのdで、ファイル内の改行コード\r
( <-CRLFのこと ) を削除します。
そのため、元ファイルがなくならないように一応別名のファイルにリダイレクトしておきます。
(> tempunix.txt
の部分。)
動作の確認後、dos形式ファイルは害悪なので削除します。
sedコマンドでも同じことができます。
$ sed -i -e 's/\r$//g' tempdos.txt
sedコマンドの-i オプションはin-placeですから、ファイルの中身が置き換わります。
安全を見るなら、下記のようにして別ファイルにリダイレクトしましょう。
$ sed -e 's/\r$//g' tempdos.txt > tempunix.txt
参考 How to convert DOS/Windows newline (CRLF) to Unix newline (LF) in a Bash script?
全てのdos形式ファイルをunix形式に変換する
上記①②を組み合わせればカレントディレクトリ上の全てのdos形式ファイルをunix形式に変換できます。
$ sed -i -e 's/\r$//g' $(file * | grep CRLF | sed 's/:.*//g')
$()
でコマンドを囲むとサブシェル上での実行結果をsed -i -e...
に渡してくれます。
一気にやりすぎて危険かもしれないので、あまりにも変換ファイル数が多いときだけに使ってください。
必ずバックアップを取ってください。