web-dev-qa-db-ja.com

UnixとWindowsの改行形式間のファイルシステムブランチ内のすべてのファイルを一括変換する方法

誰もが知っている:-) Windowsではプレーンテキストファイルの行はCR + LFで終了し、UnixとLinuxではLFのみで終了します。すべてのソースコードファイルを1つの形式から別にそして戻って?

15
Ivan

それは依存します:ファイルがバージョン管理下にある場合、これはかなり不人気な履歴汚染決定になる可能性があります。 Gitには、チェックアウト時に行末を自動的に変換するオプションがあります。

気にせず、すぐに変換したい場合は、fromdos/todosdos2unix/unix2dosなどのプログラムがこれを行います。 findfind . -type f -name '*.php' -exec dos2unix '{}' +を使用できます。

17
janmoesen

を含むいくつかの専用プログラムがあります

  • dos2unix ツールからのdos2unixおよびunix2dos
  • tofrodos ツールからのtodosおよびfromdos

適切な方向のツールを選択し、コマンドラインで変換するファイルの名前を渡すだけです。


LinuxもCygwinも持っていない場合は、次のようにします。

sed -i -e 's/\r\+$//' filename             # dos|unix -> unix
sed -i -e 's/\r*$/\r/' filename            # dos|unix -> dos

Perlを使用している場合:

Perl -i -pe 's/\r+$//' filename            # dos|unix -> unix
Perl -i -pe 's/\r*$/\r/' filename          # dos|unix -> dos

POSIXツール(BusyBoxを含む)のみを使用して、unixからdosに移行するには、CR文字を文字通りsedコマンドで渡す必要があります。

cr=$(echo | tr '\n' '\r')
sed -e "s/$cr*\$/$cr/" <filename >filename.dos
mv filename.dos filename

別の方向では、すべてのCRを削除できます。

tr -d '\r' <filename >filename.dos
mv filename.dos filename

ワイルドカードを使用して、同じディレクトリにある多くのファイルを一度に変換できます。

sed -i -e 's/\r\+$//' *.txt

現在のディレクトリとそのサブディレクトリ内のすべてのファイルを変換するには、シェルがzshの場合、**/を使用できます。

sed -i -e 's/\r\+$//' **/*.txt

Bash≥4では**/を使用できますが、最初にshopt -s globstarを実行する必要があります(この行は~/.bashrcに挿入できます)。 ksh93では**/を使用できますが、最初にset -o globstarを実行する必要があります(この行は~/.kshrcに挿入できます。

リダイレクトが必要なツールのみを使用できる場合は、forループを使用します。

for x in *.txt; do
  tr -d '\r' <"$x" >"$x.dos"
  mv -- "$x.dos" "$x"
done

**/がない場合、または変換するファイルを選択するためのより複雑なマッチングが必要な場合は、findコマンドを使用します。 Linux/Cygwinの例は、.oというファイルとbinというサブディレクトリの下のファイルを除いて、現在のディレクトリとそのサブディレクトリの下にあるすべてのファイルを再帰的に変換します。

find -name 'bin' -type d -Prune -o \
     \! -name '*.o' \
     -exec sed -i -e 's/\r\+$//' {} +

以下はPOSIXの例です。 findに、必要なリダイレクトを実行できるシェルを起動するように指示します。

find -name 'bin' -type d -Prune -o \
     \! -name '*.o' \
     -exec sh -c '
       tr -d '\r' <"$0" >"$0.dos"
       mv -- "$0.dos" "$0"
' {} \;

シェルコマンドでループを使用することにより、findメソッドを少し速くすることができますが、コードは複雑になりますが、より高速になります。

find -name 'bin' -type d -Prune -o \
     \! -name '*.o' \
     -exec sh -c '
       for x; do
         tr -d '\r' <"$x" >"$x.dos"
         mv -- "$x.dos" "$x"
       done
' _ {} +

winscptold so の場合、自動変換します。

ファイルがすべて同じディレクトリにある場合:

DIRECTORY=/your/directory
unix2dos $DIRECTORY/*
2
Nils