Как массово преобразовать все файлы в ветке файловой системы между Unix и Windows форматом разрыва строки?

14

Всем известно :-), что в Windows строки текстовых файлов заканчиваются на CR + LF, а в Unix и Linux - только на LF. Как я могу быстро конвертировать все мои файлы исходного кода из одного формата в другой и обратно?

Иван
источник

Ответы:

17

Это зависит: если файлы находятся под контролем версий, это может быть довольно непопулярным решением, загрязняющим историю. Git имеет возможность автоматически преобразовывать окончания строк при оформлении заказа.

Если вам все равно и вы хотите быстро конвертировать, есть программы типа fromdos/ todosи dos2unix/, unix2dosкоторые делают это для вас. Вы можете использовать find: find . -type f -name '*.php' -exec dos2unix '{}' +.

janmoesen
источник
7

Есть несколько специализированных программ, в том числе

  • dos2unixи unix2dosиз инструментов dos2unix
  • todosи fromdosиз инструментов Tofrodos

Просто выберите инструмент для соответствующего направления и передайте имена файлов для преобразования в командной строке.


Если у вас нет ни одного, но есть 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метод немного быстрее за счет более сложного кода, используя цикл в команде shell.

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
' _ {} +
Жиль "ТАК - перестань быть злым"
источник
2

winscp также автоматически преобразует, если так сказано .

Если ваши файлы находятся в одном каталоге:

DIRECTORY=/your/directory
unix2dos $DIRECTORY/*
Nils
источник
Можете ли вы описать немного больше, как достичь через WinSCP?
хариш шарма
@harishsharma Я добавил ссылку выше, чтобы "сказал так".
Нильс